aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/images
diff options
context:
space:
mode:
authorGravatar scroggo@google.com <scroggo@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-07-18 19:34:49 +0000
committerGravatar scroggo@google.com <scroggo@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-07-18 19:34:49 +0000
commitf698c8262df397a7015662e91b1a727e1134c418 (patch)
treeadd081995101cc29152b343ab037b4adaf9c8950 /src/images
parent97e49e97b6379cd2abb6c55b9e16246db0dad552 (diff)
Allow decoding JPEG into A8.
If the original image is grayscale, allow decoding into A8. Change the size of PrefConfigTable to allow for 8bit gray, a new source config. Add a new sampler to SkScaledBitmapSampler to 'convert' to A8. FIXME: Should there be a dithered option for gray scale? R=reed@google.com Review URL: https://codereview.chromium.org/18083026 git-svn-id: http://skia.googlecode.com/svn/trunk@10157 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/images')
-rw-r--r--src/images/SkImageDecoder.cpp26
-rw-r--r--src/images/SkImageDecoder_libjpeg.cpp20
-rw-r--r--src/images/SkScaledBitmapSampler.cpp22
3 files changed, 52 insertions, 16 deletions
diff --git a/src/images/SkImageDecoder.cpp b/src/images/SkImageDecoder.cpp
index 5d94bb1c2d..ccdc6dfcde 100644
--- a/src/images/SkImageDecoder.cpp
+++ b/src/images/SkImageDecoder.cpp
@@ -145,31 +145,37 @@ void SkImageDecoder::setPrefConfigTable(const SkBitmap::Config pref[6]) {
fUsePrefTable = false;
} else {
fUsePrefTable = true;
- memcpy(fPrefTable, pref, sizeof(fPrefTable));
+ fPrefTable.fPrefFor_8Index_NoAlpha_src = pref[0];
+ fPrefTable.fPrefFor_8Index_YesAlpha_src = pref[1];
+ fPrefTable.fPrefFor_8Gray_src = SkBitmap::kNo_Config;
+ fPrefTable.fPrefFor_8bpc_NoAlpha_src = pref[4];
+ fPrefTable.fPrefFor_8bpc_YesAlpha_src = pref[5];
}
}
+void SkImageDecoder::setPrefConfigTable(const PrefConfigTable& prefTable) {
+ fUsePrefTable = true;
+ fPrefTable = prefTable;
+}
+
SkBitmap::Config SkImageDecoder::getPrefConfig(SrcDepth srcDepth,
bool srcHasAlpha) const {
SkBitmap::Config config;
if (fUsePrefTable) {
- int index = 0;
switch (srcDepth) {
case kIndex_SrcDepth:
- index = 0;
+ config = srcHasAlpha ? fPrefTable.fPrefFor_8Index_YesAlpha_src
+ : fPrefTable.fPrefFor_8Index_NoAlpha_src;
break;
- case k16Bit_SrcDepth:
- index = 2;
+ case k8BitGray_SrcDepth:
+ config = fPrefTable.fPrefFor_8Gray_src;
break;
case k32Bit_SrcDepth:
- index = 4;
+ config = srcHasAlpha ? fPrefTable.fPrefFor_8bpc_YesAlpha_src
+ : fPrefTable.fPrefFor_8bpc_NoAlpha_src;
break;
}
- if (srcHasAlpha) {
- index += 1;
- }
- config = fPrefTable[index];
} else {
config = fDefaultPref;
}
diff --git a/src/images/SkImageDecoder_libjpeg.cpp b/src/images/SkImageDecoder_libjpeg.cpp
index bea1e98641..e4d7ace0d4 100644
--- a/src/images/SkImageDecoder_libjpeg.cpp
+++ b/src/images/SkImageDecoder_libjpeg.cpp
@@ -289,21 +289,33 @@ bool SkJPEGImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) {
/* this gives another few percents */
cinfo.do_block_smoothing = 0;
+ SrcDepth srcDepth = k32Bit_SrcDepth;
/* default format is RGB */
if (cinfo.jpeg_color_space == JCS_CMYK) {
// libjpeg cannot convert from CMYK to RGB - here we set up
// so libjpeg will give us CMYK samples back and we will
// later manually convert them to RGB
cinfo.out_color_space = JCS_CMYK;
+ } else if (cinfo.jpeg_color_space == JCS_GRAYSCALE) {
+ cinfo.out_color_space = JCS_GRAYSCALE;
+ srcDepth = k8BitGray_SrcDepth;
} else {
cinfo.out_color_space = JCS_RGB;
}
- SkBitmap::Config config = this->getPrefConfig(k32Bit_SrcDepth, false);
+ SkBitmap::Config config = this->getPrefConfig(srcDepth, false);
// only these make sense for jpegs
- if (config != SkBitmap::kARGB_8888_Config &&
- config != SkBitmap::kARGB_4444_Config &&
- config != SkBitmap::kRGB_565_Config) {
+ if (SkBitmap::kA8_Config == config) {
+ if (cinfo.jpeg_color_space != JCS_GRAYSCALE) {
+ // Converting from a non grayscale image to A8 is
+ // not currently supported.
+ config = SkBitmap::kARGB_8888_Config;
+ // Change the output from jpeg back to RGB.
+ cinfo.out_color_space = JCS_RGB;
+ }
+ } else if (config != SkBitmap::kARGB_8888_Config &&
+ config != SkBitmap::kARGB_4444_Config &&
+ config != SkBitmap::kRGB_565_Config) {
config = SkBitmap::kARGB_8888_Config;
}
diff --git a/src/images/SkScaledBitmapSampler.cpp b/src/images/SkScaledBitmapSampler.cpp
index ca41de9396..021f86ba86 100644
--- a/src/images/SkScaledBitmapSampler.cpp
+++ b/src/images/SkScaledBitmapSampler.cpp
@@ -289,6 +289,15 @@ static bool Sample_Index_DI(void* SK_RESTRICT dstRow,
return false;
}
+// A8
+static bool Sample_Gray_DA8(void* SK_RESTRICT dstRow,
+ const uint8_t* SK_RESTRICT src,
+ int width, int deltaSrc, int,
+ const SkPMColor[]) {
+ memcpy(dstRow, src, width);
+ return true;
+}
+
// 8888 Unpremul
static bool Sample_Gray_D8888_Unpremul(void* SK_RESTRICT dstRow,
@@ -396,6 +405,12 @@ bool SkScaledBitmapSampler::begin(SkBitmap* dst, SrcConfig sc, bool dither,
NULL, NULL,
Sample_Index_DI, Sample_Index_DI,
NULL, NULL,
+ // A8
+ Sample_Gray_DA8, Sample_Gray_DA8,
+ NULL, NULL,
+ NULL, NULL,
+ NULL, NULL,
+ NULL, NULL,
// 8888 Unpremul (no dither distinction)
Sample_Gray_D8888_Unpremul, Sample_Gray_D8888_Unpremul,
Sample_RGBx_D8888, Sample_RGBx_D8888,
@@ -405,7 +420,7 @@ bool SkScaledBitmapSampler::begin(SkBitmap* dst, SrcConfig sc, bool dither,
};
// The jump between dst configs in the table
static const int gProcDstConfigSpan = 10;
- SK_COMPILE_ASSERT(SK_ARRAY_COUNT(gProcs) == 5 * gProcDstConfigSpan,
+ SK_COMPILE_ASSERT(SK_ARRAY_COUNT(gProcs) == 6 * gProcDstConfigSpan,
gProcs_has_the_wrong_number_of_entries);
fCTable = ctable;
@@ -456,6 +471,9 @@ bool SkScaledBitmapSampler::begin(SkBitmap* dst, SrcConfig sc, bool dither,
case SkBitmap::kIndex8_Config:
index += 3 * gProcDstConfigSpan;
break;
+ case SkBitmap::kA8_Config:
+ index += 4 * gProcDstConfigSpan;
+ break;
default:
return false;
}
@@ -464,7 +482,7 @@ bool SkScaledBitmapSampler::begin(SkBitmap* dst, SrcConfig sc, bool dither,
if (dst->config() != SkBitmap::kARGB_8888_Config) {
return false;
}
- index += 4 * gProcDstConfigSpan;
+ index += 5 * gProcDstConfigSpan;
}
fRowProc = gProcs[index];