Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: src/images/SkPNGImageEncoder.cpp

Issue 2290843002: Add Gray support to SkPNGImageEncoder (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: use sk_bzero() Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | tests/CodecTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2006 The Android Open Source Project 2 * Copyright 2006 The Android Open Source Project
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkImageEncoder.h" 8 #include "SkImageEncoder.h"
9 #include "SkColor.h" 9 #include "SkColor.h"
10 #include "SkColorPriv.h" 10 #include "SkColorPriv.h"
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 SkColorType fColorType; 69 SkColorType fColorType;
70 bool fHasAlpha; 70 bool fHasAlpha;
71 transform_scanline_proc fProc; 71 transform_scanline_proc fProc;
72 } gMap[] = { 72 } gMap[] = {
73 { kRGB_565_SkColorType, false, transform_scanline_565 }, 73 { kRGB_565_SkColorType, false, transform_scanline_565 },
74 { kN32_SkColorType, false, transform_scanline_888 }, 74 { kN32_SkColorType, false, transform_scanline_888 },
75 { kN32_SkColorType, true, transform_scanline_8888 }, 75 { kN32_SkColorType, true, transform_scanline_8888 },
76 { kARGB_4444_SkColorType, false, transform_scanline_444 }, 76 { kARGB_4444_SkColorType, false, transform_scanline_444 },
77 { kARGB_4444_SkColorType, true, transform_scanline_4444 }, 77 { kARGB_4444_SkColorType, true, transform_scanline_4444 },
78 { kIndex_8_SkColorType, false, transform_scanline_memcpy }, 78 { kIndex_8_SkColorType, false, transform_scanline_memcpy },
79 { kGray_8_SkColorType, false, transform_scanline_memcpy },
79 }; 80 };
80 81
81 for (int i = SK_ARRAY_COUNT(gMap) - 1; i >= 0; --i) { 82 for (int i = SK_ARRAY_COUNT(gMap) - 1; i >= 0; --i) {
82 if (gMap[i].fColorType == ct && gMap[i].fHasAlpha == hasAlpha) { 83 if (gMap[i].fColorType == ct && gMap[i].fHasAlpha == hasAlpha) {
83 return gMap[i].fProc; 84 return gMap[i].fProc;
84 } 85 }
85 } 86 }
86 sk_throw(); 87 sk_throw();
87 return nullptr; 88 return nullptr;
88 } 89 }
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
171 typedef SkImageEncoder INHERITED; 172 typedef SkImageEncoder INHERITED;
172 }; 173 };
173 174
174 bool SkPNGImageEncoder::onEncode(SkWStream* stream, 175 bool SkPNGImageEncoder::onEncode(SkWStream* stream,
175 const SkBitmap& originalBitmap, 176 const SkBitmap& originalBitmap,
176 int /*quality*/) { 177 int /*quality*/) {
177 SkBitmap copy; 178 SkBitmap copy;
178 const SkBitmap* bitmap = &originalBitmap; 179 const SkBitmap* bitmap = &originalBitmap;
179 switch (originalBitmap.colorType()) { 180 switch (originalBitmap.colorType()) {
180 case kIndex_8_SkColorType: 181 case kIndex_8_SkColorType:
182 case kGray_8_SkColorType:
181 case kN32_SkColorType: 183 case kN32_SkColorType:
182 case kARGB_4444_SkColorType: 184 case kARGB_4444_SkColorType:
183 case kRGB_565_SkColorType: 185 case kRGB_565_SkColorType:
184 break; 186 break;
185 default: 187 default:
186 // TODO(scroggo): support 8888-but-not-N32 natively. 188 // TODO(scroggo): support 8888-but-not-N32 natively.
187 // TODO(scroggo): support kGray_8 directly.
188 // TODO(scroggo): support Alpha_8 as Grayscale(black)+Alpha 189 // TODO(scroggo): support Alpha_8 as Grayscale(black)+Alpha
189 if (originalBitmap.copyTo(&copy, kN32_SkColorType)) { 190 if (originalBitmap.copyTo(&copy, kN32_SkColorType)) {
190 bitmap = © 191 bitmap = ©
191 } 192 }
192 } 193 }
193 SkColorType ct = bitmap->colorType(); 194 SkColorType ct = bitmap->colorType();
194 195
195 const bool hasAlpha = !bitmap->isOpaque(); 196 const bool hasAlpha = !bitmap->isOpaque();
196 int colorType = PNG_COLOR_MASK_COLOR;
197 int bitDepth = 8; // default for color 197 int bitDepth = 8; // default for color
198 png_color_8 sig_bit; 198 png_color_8 sig_bit;
199 sk_bzero(&sig_bit, sizeof(png_color_8));
199 200
201 int colorType;
200 switch (ct) { 202 switch (ct) {
201 case kIndex_8_SkColorType: 203 case kIndex_8_SkColorType:
202 colorType |= PNG_COLOR_MASK_PALETTE; 204 sig_bit.red = 8;
203 // fall through to the ARGB_8888 case 205 sig_bit.green = 8;
206 sig_bit.blue = 8;
207 sig_bit.alpha = 8;
208 colorType = PNG_COLOR_TYPE_PALETTE;
209 break;
210 case kGray_8_SkColorType:
211 sig_bit.gray = 8;
212 colorType = PNG_COLOR_TYPE_GRAY;
213 SkASSERT(!hasAlpha);
214 break;
204 case kN32_SkColorType: 215 case kN32_SkColorType:
205 sig_bit.red = 8; 216 sig_bit.red = 8;
206 sig_bit.green = 8; 217 sig_bit.green = 8;
207 sig_bit.blue = 8; 218 sig_bit.blue = 8;
208 sig_bit.alpha = 8; 219 sig_bit.alpha = 8;
220 colorType = hasAlpha ? PNG_COLOR_TYPE_RGB_ALPHA : PNG_COLOR_TYPE_RGB ;
209 break; 221 break;
210 case kARGB_4444_SkColorType: 222 case kARGB_4444_SkColorType:
211 sig_bit.red = 4; 223 sig_bit.red = 4;
212 sig_bit.green = 4; 224 sig_bit.green = 4;
213 sig_bit.blue = 4; 225 sig_bit.blue = 4;
214 sig_bit.alpha = 4; 226 sig_bit.alpha = 4;
227 colorType = hasAlpha ? PNG_COLOR_TYPE_RGB_ALPHA : PNG_COLOR_TYPE_RGB ;
215 break; 228 break;
216 case kRGB_565_SkColorType: 229 case kRGB_565_SkColorType:
217 sig_bit.red = 5; 230 sig_bit.red = 5;
218 sig_bit.green = 6; 231 sig_bit.green = 6;
219 sig_bit.blue = 5; 232 sig_bit.blue = 5;
220 sig_bit.alpha = 0; 233 colorType = PNG_COLOR_TYPE_RGB;
234 SkASSERT(!hasAlpha);
221 break; 235 break;
222 default: 236 default:
223 return false; 237 return false;
224 } 238 }
225 239
226 if (hasAlpha) {
227 // don't specify alpha if we're a palette, even if our ctable has alpha
228 if (!(colorType & PNG_COLOR_MASK_PALETTE)) {
229 colorType |= PNG_COLOR_MASK_ALPHA;
230 }
231 } else {
232 sig_bit.alpha = 0;
233 }
234
235 SkAutoLockPixels alp(*bitmap); 240 SkAutoLockPixels alp(*bitmap);
236 // readyToDraw checks for pixels (and colortable if that is required) 241 // readyToDraw checks for pixels (and colortable if that is required)
237 if (!bitmap->readyToDraw()) { 242 if (!bitmap->readyToDraw()) {
238 return false; 243 return false;
239 } 244 }
240 245
241 // we must do this after we have locked the pixels 246 // we must do this after we have locked the pixels
242 SkColorTable* ctable = bitmap->getColorTable(); 247 SkColorTable* ctable = bitmap->getColorTable();
243 if (ctable) { 248 if (ctable) {
244 if (ctable->count() == 0) { 249 if (ctable->count() == 0) {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 png_color paletteColors[256]; 304 png_color paletteColors[256];
300 png_byte trans[256]; 305 png_byte trans[256];
301 if (kIndex_8_SkColorType == ct) { 306 if (kIndex_8_SkColorType == ct) {
302 SkColorTable* ct = bitmap.getColorTable(); 307 SkColorTable* ct = bitmap.getColorTable();
303 int numTrans = pack_palette(ct, paletteColors, trans, hasAlpha); 308 int numTrans = pack_palette(ct, paletteColors, trans, hasAlpha);
304 png_set_PLTE(png_ptr, info_ptr, paletteColors, ct->count()); 309 png_set_PLTE(png_ptr, info_ptr, paletteColors, ct->count());
305 if (numTrans > 0) { 310 if (numTrans > 0) {
306 png_set_tRNS(png_ptr, info_ptr, trans, numTrans, nullptr); 311 png_set_tRNS(png_ptr, info_ptr, trans, numTrans, nullptr);
307 } 312 }
308 } 313 }
309 #ifdef PNG_sBIT_SUPPORTED 314
310 png_set_sBIT(png_ptr, info_ptr, &sig_bit); 315 png_set_sBIT(png_ptr, info_ptr, &sig_bit);
311 #endif
312 png_write_info(png_ptr, info_ptr); 316 png_write_info(png_ptr, info_ptr);
313 317
314 const char* srcImage = (const char*)bitmap.getPixels(); 318 const char* srcImage = (const char*)bitmap.getPixels();
315 SkAutoSTMalloc<1024, char> rowStorage(bitmap.width() << 2); 319 SkAutoSTMalloc<1024, char> rowStorage(bitmap.width() << 2);
316 char* storage = rowStorage.get(); 320 char* storage = rowStorage.get();
317 transform_scanline_proc proc = choose_proc(ct, hasAlpha); 321 transform_scanline_proc proc = choose_proc(ct, hasAlpha);
318 322
319 for (int y = 0; y < bitmap.height(); y++) { 323 for (int y = 0; y < bitmap.height(); y++) {
320 png_bytep row_ptr = (png_bytep)storage; 324 png_bytep row_ptr = (png_bytep)storage;
321 proc(srcImage, bitmap.width(), storage); 325 proc(srcImage, bitmap.width(), storage);
(...skipping 10 matching lines...) Expand all
332 336
333 /////////////////////////////////////////////////////////////////////////////// 337 ///////////////////////////////////////////////////////////////////////////////
334 DEFINE_ENCODER_CREATOR(PNGImageEncoder); 338 DEFINE_ENCODER_CREATOR(PNGImageEncoder);
335 /////////////////////////////////////////////////////////////////////////////// 339 ///////////////////////////////////////////////////////////////////////////////
336 340
337 SkImageEncoder* sk_libpng_efactory(SkImageEncoder::Type t) { 341 SkImageEncoder* sk_libpng_efactory(SkImageEncoder::Type t) {
338 return (SkImageEncoder::kPNG_Type == t) ? new SkPNGImageEncoder : nullptr; 342 return (SkImageEncoder::kPNG_Type == t) ? new SkPNGImageEncoder : nullptr;
339 } 343 }
340 344
341 static SkImageEncoder_EncodeReg gEReg(sk_libpng_efactory); 345 static SkImageEncoder_EncodeReg gEReg(sk_libpng_efactory);
OLDNEW
« no previous file with comments | « no previous file | tests/CodecTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698