Extract transform_scanline_XXXX functions into transform_scanline.h for code-sharing
authorepoger@google.com <epoger@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Fri, 16 Nov 2012 18:44:18 +0000 (18:44 +0000)
committerepoger@google.com <epoger@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Fri, 16 Nov 2012 18:44:18 +0000 (18:44 +0000)
Review URL: https://codereview.appspot.com/6849065

git-svn-id: http://skia.googlecode.com/svn/trunk@6468 2bbb7eff-a529-9590-31e7-b0007b416f81

include/images/SkImageEncoder.h
src/images/SkImageDecoder_libpng.cpp
src/images/transform_scanline.h [new file with mode: 0644]

index 5e350d4..3fbfefa 100644 (file)
@@ -28,8 +28,25 @@ public:
         kDefaultQuality = 80
     };
 
-    bool encodeFile(const char file[], const SkBitmap&, int quality);
-    bool encodeStream(SkWStream*, const SkBitmap&, int quality);
+    /**
+     * Encode bitmap 'bm' in the desired format, writing results to
+     * file 'file', at quality level 'quality' (which can be in range
+     * 0-100).
+     *
+     * Calls the particular implementation's onEncode() method to
+     * actually do the encoding.
+     */
+    bool encodeFile(const char file[], const SkBitmap& bm, int quality);
+
+    /**
+     * Encode bitmap 'bm' in the desired format, writing results to
+     * stream 'stream', at quality level 'quality' (which can be in
+     * range 0-100).
+     *
+     * Calls the particular implementation's onEncode() method to
+     * actually do the encoding.
+     */
+    bool encodeStream(SkWStream* stream, const SkBitmap& bm, int quality);
 
     static bool EncodeFile(const char file[], const SkBitmap&, Type,
                            int quality);
@@ -37,7 +54,14 @@ public:
                            int quality);
 
 protected:
-    virtual bool onEncode(SkWStream*, const SkBitmap&, int quality) = 0;
+    /**
+     * Encode bitmap 'bm' in the desired format, writing results to
+     * stream 'stream', at quality level 'quality' (which can be in
+     * range 0-100).
+     *
+     * This must be overridden by each SkImageEncoder implementation.
+     */
+    virtual bool onEncode(SkWStream* stream, const SkBitmap& bm, int quality) = 0;
 };
 
 // This macro declares a global (i.e., non-class owned) creation entry point
index d48bce5..cca69fa 100644 (file)
@@ -17,6 +17,7 @@
 #include "SkStream.h"
 #include "SkTemplates.h"
 #include "SkUtils.h"
+#include "transform_scanline.h"
 
 extern "C" {
 #include "png.h"
@@ -503,99 +504,6 @@ static void sk_write_fn(png_structp png_ptr, png_bytep data, png_size_t len) {
     }
 }
 
-typedef void (*transform_scanline_proc)(const char* SK_RESTRICT src,
-                                        int width, char* SK_RESTRICT dst);
-
-static void transform_scanline_565(const char* SK_RESTRICT src, int width,
-                                   char* SK_RESTRICT dst) {
-    const uint16_t* SK_RESTRICT srcP = (const uint16_t*)src;
-    for (int i = 0; i < width; i++) {
-        unsigned c = *srcP++;
-        *dst++ = SkPacked16ToR32(c);
-        *dst++ = SkPacked16ToG32(c);
-        *dst++ = SkPacked16ToB32(c);
-    }
-}
-
-static void transform_scanline_888(const char* SK_RESTRICT src, int width,
-                                   char* SK_RESTRICT dst) {
-    const SkPMColor* SK_RESTRICT srcP = (const SkPMColor*)src;
-    for (int i = 0; i < width; i++) {
-        SkPMColor c = *srcP++;
-        *dst++ = SkGetPackedR32(c);
-        *dst++ = SkGetPackedG32(c);
-        *dst++ = SkGetPackedB32(c);
-    }
-}
-
-static void transform_scanline_444(const char* SK_RESTRICT src, int width,
-                                   char* SK_RESTRICT dst) {
-    const SkPMColor16* SK_RESTRICT srcP = (const SkPMColor16*)src;
-    for (int i = 0; i < width; i++) {
-        SkPMColor16 c = *srcP++;
-        *dst++ = SkPacked4444ToR32(c);
-        *dst++ = SkPacked4444ToG32(c);
-        *dst++ = SkPacked4444ToB32(c);
-    }
-}
-
-static void transform_scanline_8888(const char* SK_RESTRICT src, int width,
-                                    char* SK_RESTRICT dst) {
-    const SkPMColor* SK_RESTRICT srcP = (const SkPMColor*)src;
-    const SkUnPreMultiply::Scale* SK_RESTRICT table =
-                                              SkUnPreMultiply::GetScaleTable();
-
-    for (int i = 0; i < width; i++) {
-        SkPMColor c = *srcP++;
-        unsigned a = SkGetPackedA32(c);
-        unsigned r = SkGetPackedR32(c);
-        unsigned g = SkGetPackedG32(c);
-        unsigned b = SkGetPackedB32(c);
-
-        if (0 != a && 255 != a) {
-            SkUnPreMultiply::Scale scale = table[a];
-            r = SkUnPreMultiply::ApplyScale(scale, r);
-            g = SkUnPreMultiply::ApplyScale(scale, g);
-            b = SkUnPreMultiply::ApplyScale(scale, b);
-        }
-        *dst++ = r;
-        *dst++ = g;
-        *dst++ = b;
-        *dst++ = a;
-    }
-}
-
-static void transform_scanline_4444(const char* SK_RESTRICT src, int width,
-                                    char* SK_RESTRICT dst) {
-    const SkPMColor16* SK_RESTRICT srcP = (const SkPMColor16*)src;
-    const SkUnPreMultiply::Scale* SK_RESTRICT table =
-                                              SkUnPreMultiply::GetScaleTable();
-
-    for (int i = 0; i < width; i++) {
-        SkPMColor16 c = *srcP++;
-        unsigned a = SkPacked4444ToA32(c);
-        unsigned r = SkPacked4444ToR32(c);
-        unsigned g = SkPacked4444ToG32(c);
-        unsigned b = SkPacked4444ToB32(c);
-
-        if (0 != a && 255 != a) {
-            SkUnPreMultiply::Scale scale = table[a];
-            r = SkUnPreMultiply::ApplyScale(scale, r);
-            g = SkUnPreMultiply::ApplyScale(scale, g);
-            b = SkUnPreMultiply::ApplyScale(scale, b);
-        }
-        *dst++ = r;
-        *dst++ = g;
-        *dst++ = b;
-        *dst++ = a;
-    }
-}
-
-static void transform_scanline_index8(const char* SK_RESTRICT src, int width,
-                                      char* SK_RESTRICT dst) {
-    memcpy(dst, src, width);
-}
-
 static transform_scanline_proc choose_proc(SkBitmap::Config config,
                                            bool hasAlpha) {
     // we don't care about search on alpha if we're kIndex8, since only the
@@ -614,7 +522,7 @@ static transform_scanline_proc choose_proc(SkBitmap::Config config,
         { SkBitmap::kARGB_8888_Config,  true,   transform_scanline_8888 },
         { SkBitmap::kARGB_4444_Config,  false,  transform_scanline_444 },
         { SkBitmap::kARGB_4444_Config,  true,   transform_scanline_4444 },
-        { SkBitmap::kIndex8_Config,     false,   transform_scanline_index8 },
+        { SkBitmap::kIndex8_Config,     false,  transform_scanline_memcpy },
     };
 
     for (int i = SK_ARRAY_COUNT(gMap) - 1; i >= 0; --i) {
diff --git a/src/images/transform_scanline.h b/src/images/transform_scanline.h
new file mode 100644 (file)
index 0000000..36efdd8
--- /dev/null
@@ -0,0 +1,140 @@
+
+/*
+ * Copyright 2012 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**
+ * Functions to transform scanlines between packed-pixel formats.
+ */
+
+#include "SkBitmap.h"
+#include "SkColor.h"
+#include "SkColorPriv.h"
+#include "SkPreConfig.h"
+#include "SkUnPreMultiply.h"
+
+/**
+ * Function template for transforming scanlines.
+ * Transform 'width' pixels from 'src' buffer into 'dst' buffer,
+ * repacking color channel data as appropriate for the given transformation.
+ */
+typedef void (*transform_scanline_proc)(const char* SK_RESTRICT src,
+                                        int width, char* SK_RESTRICT dst);
+
+/**
+ * Identity transformation: just copy bytes from src to dst.
+ */
+static void transform_scanline_memcpy(const char* SK_RESTRICT src, int width,
+                                      char* SK_RESTRICT dst) {
+    memcpy(dst, src, width);
+}
+
+/**
+ * Transform from kRGB_565_Config to 3-bytes-per-pixel RGB.
+ * Alpha channel data is not present in kRGB_565_Config format, so there is no
+ * alpha channel data to preserve.
+ */
+static void transform_scanline_565(const char* SK_RESTRICT src, int width,
+                                   char* SK_RESTRICT dst) {
+    const uint16_t* SK_RESTRICT srcP = (const uint16_t*)src;
+    for (int i = 0; i < width; i++) {
+        unsigned c = *srcP++;
+        *dst++ = SkPacked16ToR32(c);
+        *dst++ = SkPacked16ToG32(c);
+        *dst++ = SkPacked16ToB32(c);
+    }
+}
+
+/**
+ * Transform from kARGB_8888_Config to 3-bytes-per-pixel RGB.
+ * Alpha channel data, if any, is abandoned.
+ */
+static void transform_scanline_888(const char* SK_RESTRICT src, int width,
+                                   char* SK_RESTRICT dst) {
+    const SkPMColor* SK_RESTRICT srcP = (const SkPMColor*)src;
+    for (int i = 0; i < width; i++) {
+        SkPMColor c = *srcP++;
+        *dst++ = SkGetPackedR32(c);
+        *dst++ = SkGetPackedG32(c);
+        *dst++ = SkGetPackedB32(c);
+    }
+}
+
+/**
+ * Transform from kARGB_4444_Config to 3-bytes-per-pixel RGB.
+ * Alpha channel data, if any, is abandoned.
+ */
+static void transform_scanline_444(const char* SK_RESTRICT src, int width,
+                                   char* SK_RESTRICT dst) {
+    const SkPMColor16* SK_RESTRICT srcP = (const SkPMColor16*)src;
+    for (int i = 0; i < width; i++) {
+        SkPMColor16 c = *srcP++;
+        *dst++ = SkPacked4444ToR32(c);
+        *dst++ = SkPacked4444ToG32(c);
+        *dst++ = SkPacked4444ToB32(c);
+    }
+}
+
+/**
+ * Transform from kARGB_8888_Config to 4-bytes-per-pixel RGBA.
+ * (This would be the identity transformation, except for byte-order and
+ * scaling of RGB based on alpha channel).
+ */
+static void transform_scanline_8888(const char* SK_RESTRICT src, int width,
+                                    char* SK_RESTRICT dst) {
+    const SkPMColor* SK_RESTRICT srcP = (const SkPMColor*)src;
+    const SkUnPreMultiply::Scale* SK_RESTRICT table =
+                                              SkUnPreMultiply::GetScaleTable();
+
+    for (int i = 0; i < width; i++) {
+        SkPMColor c = *srcP++;
+        unsigned a = SkGetPackedA32(c);
+        unsigned r = SkGetPackedR32(c);
+        unsigned g = SkGetPackedG32(c);
+        unsigned b = SkGetPackedB32(c);
+
+        if (0 != a && 255 != a) {
+            SkUnPreMultiply::Scale scale = table[a];
+            r = SkUnPreMultiply::ApplyScale(scale, r);
+            g = SkUnPreMultiply::ApplyScale(scale, g);
+            b = SkUnPreMultiply::ApplyScale(scale, b);
+        }
+        *dst++ = r;
+        *dst++ = g;
+        *dst++ = b;
+        *dst++ = a;
+    }
+}
+
+/**
+ * Transform from kARGB_8888_Config to 4-bytes-per-pixel RGBA,
+ * with scaling of RGB based on alpha channel.
+ */
+static void transform_scanline_4444(const char* SK_RESTRICT src, int width,
+                                    char* SK_RESTRICT dst) {
+    const SkPMColor16* SK_RESTRICT srcP = (const SkPMColor16*)src;
+    const SkUnPreMultiply::Scale* SK_RESTRICT table =
+                                              SkUnPreMultiply::GetScaleTable();
+
+    for (int i = 0; i < width; i++) {
+        SkPMColor16 c = *srcP++;
+        unsigned a = SkPacked4444ToA32(c);
+        unsigned r = SkPacked4444ToR32(c);
+        unsigned g = SkPacked4444ToG32(c);
+        unsigned b = SkPacked4444ToB32(c);
+
+        if (0 != a && 255 != a) {
+            SkUnPreMultiply::Scale scale = table[a];
+            r = SkUnPreMultiply::ApplyScale(scale, r);
+            g = SkUnPreMultiply::ApplyScale(scale, g);
+            b = SkUnPreMultiply::ApplyScale(scale, b);
+        }
+        *dst++ = r;
+        *dst++ = g;
+        *dst++ = b;
+        *dst++ = a;
+    }
+}