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

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

Issue 2288163003: Add Alpha8 support to SkPNGImageEncoder Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: 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
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 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 { kGray_8_SkColorType, false, transform_scanline_memcpy },
80 { kAlpha_8_SkColorType, true, transform_scanline_memcpy },
80 }; 81 };
81 82
82 for (int i = SK_ARRAY_COUNT(gMap) - 1; i >= 0; --i) { 83 for (int i = SK_ARRAY_COUNT(gMap) - 1; i >= 0; --i) {
83 if (gMap[i].fColorType == ct && gMap[i].fHasAlpha == hasAlpha) { 84 if (gMap[i].fColorType == ct && gMap[i].fHasAlpha == hasAlpha) {
84 return gMap[i].fProc; 85 return gMap[i].fProc;
85 } 86 }
86 } 87 }
87 sk_throw(); 88 sk_throw();
88 return nullptr; 89 return nullptr;
89 } 90 }
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 }; 174 };
174 175
175 bool SkPNGImageEncoder::onEncode(SkWStream* stream, 176 bool SkPNGImageEncoder::onEncode(SkWStream* stream,
176 const SkBitmap& originalBitmap, 177 const SkBitmap& originalBitmap,
177 int /*quality*/) { 178 int /*quality*/) {
178 SkBitmap copy; 179 SkBitmap copy;
179 const SkBitmap* bitmap = &originalBitmap; 180 const SkBitmap* bitmap = &originalBitmap;
180 switch (originalBitmap.colorType()) { 181 switch (originalBitmap.colorType()) {
181 case kIndex_8_SkColorType: 182 case kIndex_8_SkColorType:
182 case kGray_8_SkColorType: 183 case kGray_8_SkColorType:
184 case kAlpha_8_SkColorType:
183 case kN32_SkColorType: 185 case kN32_SkColorType:
184 case kARGB_4444_SkColorType: 186 case kARGB_4444_SkColorType:
185 case kRGB_565_SkColorType: 187 case kRGB_565_SkColorType:
186 break; 188 break;
187 default: 189 default:
188 // TODO(scroggo): support 8888-but-not-N32 natively. 190 // TODO(scroggo): support 8888-but-not-N32 natively.
189 // TODO(scroggo): support Alpha_8 as Grayscale(black)+Alpha
190 if (originalBitmap.copyTo(&copy, kN32_SkColorType)) { 191 if (originalBitmap.copyTo(&copy, kN32_SkColorType)) {
191 bitmap = © 192 bitmap = ©
192 } 193 }
193 } 194 }
194 SkColorType ct = bitmap->colorType(); 195 SkColorType ct = bitmap->colorType();
195 196
196 const bool hasAlpha = !bitmap->isOpaque(); 197 const bool hasAlpha = !bitmap->isOpaque();
197 int bitDepth = 8; // default for color 198 int bitDepth = 8; // default for color
198 png_color_8 sig_bit; 199 png_color_8 sig_bit;
199 sk_bzero(&sig_bit, sizeof(png_color_8)); 200 sk_bzero(&sig_bit, sizeof(png_color_8));
200 201
201 int colorType; 202 int colorType;
202 switch (ct) { 203 switch (ct) {
203 case kIndex_8_SkColorType: 204 case kIndex_8_SkColorType:
204 sig_bit.red = 8; 205 sig_bit.red = 8;
205 sig_bit.green = 8; 206 sig_bit.green = 8;
206 sig_bit.blue = 8; 207 sig_bit.blue = 8;
207 sig_bit.alpha = 8; 208 sig_bit.alpha = 8;
208 colorType = PNG_COLOR_TYPE_PALETTE; 209 colorType = PNG_COLOR_TYPE_PALETTE;
209 break; 210 break;
210 case kGray_8_SkColorType: 211 case kGray_8_SkColorType:
211 sig_bit.gray = 8; 212 sig_bit.gray = 8;
212 colorType = PNG_COLOR_TYPE_GRAY; 213 colorType = PNG_COLOR_TYPE_GRAY;
213 SkASSERT(!hasAlpha); 214 SkASSERT(!hasAlpha);
214 break; 215 break;
216 case kAlpha_8_SkColorType:
217 // This is a bit of a trick. PNG does not have an alpha-only format , so
218 // we tell libpng that we are encoding a gray image. We'll also enc ode
219 // an extra custom chunk, so our decoder knows that the image is act ually
220 // Alpha8.
221 sig_bit.gray = 8;
222 colorType = PNG_COLOR_TYPE_GRAY;
223 SkASSERT(hasAlpha);
224 break;
215 case kN32_SkColorType: 225 case kN32_SkColorType:
216 sig_bit.red = 8; 226 sig_bit.red = 8;
217 sig_bit.green = 8; 227 sig_bit.green = 8;
218 sig_bit.blue = 8; 228 sig_bit.blue = 8;
219 sig_bit.alpha = 8; 229 sig_bit.alpha = 8;
220 colorType = hasAlpha ? PNG_COLOR_TYPE_RGB_ALPHA : PNG_COLOR_TYPE_RGB ; 230 colorType = hasAlpha ? PNG_COLOR_TYPE_RGB_ALPHA : PNG_COLOR_TYPE_RGB ;
221 break; 231 break;
222 case kARGB_4444_SkColorType: 232 case kARGB_4444_SkColorType:
223 sig_bit.red = 4; 233 sig_bit.red = 4;
224 sig_bit.green = 4; 234 sig_bit.green = 4;
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 if (kIndex_8_SkColorType == ct) { 316 if (kIndex_8_SkColorType == ct) {
307 SkColorTable* ct = bitmap.getColorTable(); 317 SkColorTable* ct = bitmap.getColorTable();
308 int numTrans = pack_palette(ct, paletteColors, trans, hasAlpha); 318 int numTrans = pack_palette(ct, paletteColors, trans, hasAlpha);
309 png_set_PLTE(png_ptr, info_ptr, paletteColors, ct->count()); 319 png_set_PLTE(png_ptr, info_ptr, paletteColors, ct->count());
310 if (numTrans > 0) { 320 if (numTrans > 0) {
311 png_set_tRNS(png_ptr, info_ptr, trans, numTrans, nullptr); 321 png_set_tRNS(png_ptr, info_ptr, trans, numTrans, nullptr);
312 } 322 }
313 } 323 }
314 324
315 png_set_sBIT(png_ptr, info_ptr, &sig_bit); 325 png_set_sBIT(png_ptr, info_ptr, &sig_bit);
326
327 if (kAlpha_8_SkColorType == ct) {
328 static constexpr char key[] = "SkColorType";
329 static constexpr char value[] = "Alpha8";
330
331 png_text text;
332 text.compression = 0; // Use deflate for text compression.
333 text.key = const_cast<char*>(key);
334 text.text = const_cast<char*>(value);
335 text.text_length = sizeof(value) - 1;
336 text.itxt_length = 0;
337 text.lang = nullptr;
338 text.lang_key = nullptr;
339 png_set_text(png_ptr, info_ptr, &text, 1);
340 }
341
316 png_write_info(png_ptr, info_ptr); 342 png_write_info(png_ptr, info_ptr);
317 343
318 const char* srcImage = (const char*)bitmap.getPixels(); 344 const char* srcImage = (const char*)bitmap.getPixels();
319 SkAutoSTMalloc<1024, char> rowStorage(bitmap.width() << 2); 345 SkAutoSTMalloc<1024, char> rowStorage(bitmap.width() << 2);
320 char* storage = rowStorage.get(); 346 char* storage = rowStorage.get();
321 transform_scanline_proc proc = choose_proc(ct, hasAlpha); 347 transform_scanline_proc proc = choose_proc(ct, hasAlpha);
322 348
323 for (int y = 0; y < bitmap.height(); y++) { 349 for (int y = 0; y < bitmap.height(); y++) {
324 png_bytep row_ptr = (png_bytep)storage; 350 png_bytep row_ptr = (png_bytep)storage;
325 proc(srcImage, bitmap.width(), storage); 351 proc(srcImage, bitmap.width(), storage);
(...skipping 10 matching lines...) Expand all
336 362
337 /////////////////////////////////////////////////////////////////////////////// 363 ///////////////////////////////////////////////////////////////////////////////
338 DEFINE_ENCODER_CREATOR(PNGImageEncoder); 364 DEFINE_ENCODER_CREATOR(PNGImageEncoder);
339 /////////////////////////////////////////////////////////////////////////////// 365 ///////////////////////////////////////////////////////////////////////////////
340 366
341 SkImageEncoder* sk_libpng_efactory(SkImageEncoder::Type t) { 367 SkImageEncoder* sk_libpng_efactory(SkImageEncoder::Type t) {
342 return (SkImageEncoder::kPNG_Type == t) ? new SkPNGImageEncoder : nullptr; 368 return (SkImageEncoder::kPNG_Type == t) ? new SkPNGImageEncoder : nullptr;
343 } 369 }
344 370
345 static SkImageEncoder_EncodeReg gEReg(sk_libpng_efactory); 371 static SkImageEncoder_EncodeReg gEReg(sk_libpng_efactory);
OLDNEW
« src/codec/SkPngCodec.cpp ('K') | « src/codec/SkSwizzler.cpp ('k') | tests/CodecTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698