OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
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 "SkColorPriv.h" | 8 #include "SkColorPriv.h" |
9 #include "SkData.h" | 9 #include "SkData.h" |
10 #include "SkDeflate.h" | 10 #include "SkDeflate.h" |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 static U8CPU SkGetR32Component(uint32_t value, SkColorType ct) { | 85 static U8CPU SkGetR32Component(uint32_t value, SkColorType ct) { |
86 return (value >> (SkIsBGRA(ct) ? SK_BGRA_R32_SHIFT : SK_RGBA_R32_SHIFT)) & 0
xFF; | 86 return (value >> (SkIsBGRA(ct) ? SK_BGRA_R32_SHIFT : SK_RGBA_R32_SHIFT)) & 0
xFF; |
87 } | 87 } |
88 static U8CPU SkGetG32Component(uint32_t value, SkColorType ct) { | 88 static U8CPU SkGetG32Component(uint32_t value, SkColorType ct) { |
89 return (value >> (SkIsBGRA(ct) ? SK_BGRA_G32_SHIFT : SK_RGBA_G32_SHIFT)) & 0
xFF; | 89 return (value >> (SkIsBGRA(ct) ? SK_BGRA_G32_SHIFT : SK_RGBA_G32_SHIFT)) & 0
xFF; |
90 } | 90 } |
91 static U8CPU SkGetB32Component(uint32_t value, SkColorType ct) { | 91 static U8CPU SkGetB32Component(uint32_t value, SkColorType ct) { |
92 return (value >> (SkIsBGRA(ct) ? SK_BGRA_B32_SHIFT : SK_RGBA_B32_SHIFT)) & 0
xFF; | 92 return (value >> (SkIsBGRA(ct) ? SK_BGRA_B32_SHIFT : SK_RGBA_B32_SHIFT)) & 0
xFF; |
93 } | 93 } |
94 | 94 |
95 | |
96 // unpremultiply and extract R, G, B components. | 95 // unpremultiply and extract R, G, B components. |
97 static void pmcolor_to_rgb24(uint32_t color, uint8_t* rgb, SkColorType ct) { | 96 static void pmcolor_to_rgb24(uint32_t color, uint8_t* rgb, SkColorType ct) { |
98 uint32_t s = SkUnPreMultiply::GetScale(SkGetA32Component(color, ct)); | 97 uint32_t s = SkUnPreMultiply::GetScale(SkGetA32Component(color, ct)); |
99 rgb[0] = SkUnPreMultiply::ApplyScale(s, SkGetR32Component(color, ct)); | 98 rgb[0] = SkUnPreMultiply::ApplyScale(s, SkGetR32Component(color, ct)); |
100 rgb[1] = SkUnPreMultiply::ApplyScale(s, SkGetG32Component(color, ct)); | 99 rgb[1] = SkUnPreMultiply::ApplyScale(s, SkGetG32Component(color, ct)); |
101 rgb[2] = SkUnPreMultiply::ApplyScale(s, SkGetB32Component(color, ct)); | 100 rgb[2] = SkUnPreMultiply::ApplyScale(s, SkGetB32Component(color, ct)); |
102 } | 101 } |
103 | 102 |
104 /* It is necessary to average the color component of transparent | 103 /* It is necessary to average the color component of transparent |
105 pixels with their surrounding neighbors since the PDF renderer may | 104 pixels with their surrounding neighbors since the PDF renderer may |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 if (!bitmap.getPixels()) { | 175 if (!bitmap.getPixels()) { |
177 size_t size = pixel_count(bitmap) * | 176 size_t size = pixel_count(bitmap) * |
178 pdf_color_component_count(bitmap.colorType()); | 177 pdf_color_component_count(bitmap.colorType()); |
179 fill_stream(out, '\x00', size); | 178 fill_stream(out, '\x00', size); |
180 return; | 179 return; |
181 } | 180 } |
182 SkBitmap copy; | 181 SkBitmap copy; |
183 const SkBitmap& bm = not4444(bitmap, ©); | 182 const SkBitmap& bm = not4444(bitmap, ©); |
184 SkAutoLockPixels autoLockPixels(bm); | 183 SkAutoLockPixels autoLockPixels(bm); |
185 SkColorType colorType = bm.colorType(); | 184 SkColorType colorType = bm.colorType(); |
| 185 SkAlphaType alphaType = bm.alphaType(); |
186 switch (colorType) { | 186 switch (colorType) { |
187 case kRGBA_8888_SkColorType: | 187 case kRGBA_8888_SkColorType: |
188 case kBGRA_8888_SkColorType: { | 188 case kBGRA_8888_SkColorType: { |
189 SkASSERT(3 == pdf_color_component_count(colorType)); | 189 SkASSERT(3 == pdf_color_component_count(colorType)); |
190 SkAutoTMalloc<uint8_t> scanline(3 * bm.width()); | 190 SkAutoTMalloc<uint8_t> scanline(3 * bm.width()); |
191 for (int y = 0; y < bm.height(); ++y) { | 191 for (int y = 0; y < bm.height(); ++y) { |
192 const uint32_t* src = bm.getAddr32(0, y); | 192 const uint32_t* src = bm.getAddr32(0, y); |
193 uint8_t* dst = scanline.get(); | 193 uint8_t* dst = scanline.get(); |
194 for (int x = 0; x < bm.width(); ++x) { | 194 for (int x = 0; x < bm.width(); ++x) { |
195 uint32_t color = *src++; | 195 if (alphaType == kPremul_SkAlphaType) { |
196 U8CPU alpha = SkGetA32Component(color, colorType); | 196 uint32_t color = *src++; |
197 if (alpha != SK_AlphaTRANSPARENT) { | 197 U8CPU alpha = SkGetA32Component(color, colorType); |
198 pmcolor_to_rgb24(color, dst, colorType); | 198 if (alpha != SK_AlphaTRANSPARENT) { |
| 199 pmcolor_to_rgb24(color, dst, colorType); |
| 200 } else { |
| 201 get_neighbor_avg_color(bm, x, y, dst, colorType); |
| 202 } |
| 203 dst += 3; |
199 } else { | 204 } else { |
200 get_neighbor_avg_color(bm, x, y, dst, colorType); | 205 uint32_t color = *src++; |
| 206 *dst++ = SkGetR32Component(color, colorType); |
| 207 *dst++ = SkGetG32Component(color, colorType); |
| 208 *dst++ = SkGetB32Component(color, colorType); |
201 } | 209 } |
202 dst += 3; | |
203 } | 210 } |
204 out->write(scanline.get(), 3 * bm.width()); | 211 out->write(scanline.get(), 3 * bm.width()); |
205 } | 212 } |
206 return; | 213 return; |
207 } | 214 } |
208 case kRGB_565_SkColorType: { | 215 case kRGB_565_SkColorType: { |
209 SkASSERT(3 == pdf_color_component_count(colorType)); | 216 SkASSERT(3 == pdf_color_component_count(colorType)); |
210 SkAutoTMalloc<uint8_t> scanline(3 * bm.width()); | 217 SkAutoTMalloc<uint8_t> scanline(3 * bm.width()); |
211 for (int y = 0; y < bm.height(); ++y) { | 218 for (int y = 0; y < bm.height(); ++y) { |
212 const uint16_t* src = bm.getAddr16(0, y); | 219 const uint16_t* src = bm.getAddr16(0, y); |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
290 return; | 297 return; |
291 case kARGB_4444_SkColorType: | 298 case kARGB_4444_SkColorType: |
292 SkDEBUGFAIL("4444 color type should have been converted to N32"); | 299 SkDEBUGFAIL("4444 color type should have been converted to N32"); |
293 return; | 300 return; |
294 case kUnknown_SkColorType: | 301 case kUnknown_SkColorType: |
295 default: | 302 default: |
296 SkDEBUGFAIL("unexpected color type"); | 303 SkDEBUGFAIL("unexpected color type"); |
297 } | 304 } |
298 } | 305 } |
299 | 306 |
300 static sk_sp<SkPDFArray> make_indexed_color_space(const SkColorTable* table) { | 307 static sk_sp<SkPDFArray> make_indexed_color_space( |
| 308 const SkColorTable* table, |
| 309 SkAlphaType alphaType) { |
301 auto result = sk_make_sp<SkPDFArray>(); | 310 auto result = sk_make_sp<SkPDFArray>(); |
302 result->reserve(4); | 311 result->reserve(4); |
303 result->appendName("Indexed"); | 312 result->appendName("Indexed"); |
304 result->appendName("DeviceRGB"); | 313 result->appendName("DeviceRGB"); |
305 SkASSERT(table); | 314 SkASSERT(table); |
306 if (table->count() < 1) { | 315 if (table->count() < 1) { |
307 result->appendInt(0); | 316 result->appendInt(0); |
308 char shortTableArray[3] = {0, 0, 0}; | 317 char shortTableArray[3] = {0, 0, 0}; |
309 SkString tableString(shortTableArray, SK_ARRAY_COUNT(shortTableArray)); | 318 SkString tableString(shortTableArray, SK_ARRAY_COUNT(shortTableArray)); |
310 result->appendString(tableString); | 319 result->appendString(tableString); |
311 return result; | 320 return result; |
312 } | 321 } |
313 result->appendInt(table->count() - 1); // maximum color index. | 322 result->appendInt(table->count() - 1); // maximum color index. |
314 | 323 |
315 // Potentially, this could be represented in fewer bytes with a stream. | 324 // Potentially, this could be represented in fewer bytes with a stream. |
316 // Max size as a string is 1.5k. | 325 // Max size as a string is 1.5k. |
317 char tableArray[256 * 3]; | 326 char tableArray[256 * 3]; |
318 SkASSERT(3u * table->count() <= SK_ARRAY_COUNT(tableArray)); | 327 SkASSERT(3u * table->count() <= SK_ARRAY_COUNT(tableArray)); |
319 uint8_t* tablePtr = reinterpret_cast<uint8_t*>(tableArray); | 328 uint8_t* tablePtr = reinterpret_cast<uint8_t*>(tableArray); |
320 const SkPMColor* colors = table->readColors(); | 329 const SkPMColor* colors = table->readColors(); |
321 for (int i = 0; i < table->count(); i++) { | 330 for (int i = 0; i < table->count(); i++) { |
322 pmcolor_to_rgb24(colors[i], tablePtr, kN32_SkColorType); | 331 if (alphaType == kPremul_SkAlphaType) { |
323 tablePtr += 3; | 332 pmcolor_to_rgb24(colors[i], tablePtr, kN32_SkColorType); |
| 333 tablePtr += 3; |
| 334 } else { |
| 335 *tablePtr++ = SkGetR32Component(colors[i], kN32_SkColorType); |
| 336 *tablePtr++ = SkGetG32Component(colors[i], kN32_SkColorType); |
| 337 *tablePtr++ = SkGetB32Component(colors[i], kN32_SkColorType); |
| 338 } |
324 } | 339 } |
325 SkString tableString(tableArray, 3 * table->count()); | 340 SkString tableString(tableArray, 3 * table->count()); |
326 result->appendString(tableString); | 341 result->appendString(tableString); |
327 return result; | 342 return result; |
328 } | 343 } |
329 | 344 |
330 static void emit_image_xobject(SkWStream* stream, | 345 static void emit_image_xobject(SkWStream* stream, |
331 const SkImage* image, | 346 const SkImage* image, |
332 bool alpha, | 347 bool alpha, |
333 const sk_sp<SkPDFObject>& smask, | 348 const sk_sp<SkPDFObject>& smask, |
(...skipping 16 matching lines...) Expand all Loading... |
350 | 365 |
351 SkPDFDict pdfDict("XObject"); | 366 SkPDFDict pdfDict("XObject"); |
352 pdfDict.insertName("Subtype", "Image"); | 367 pdfDict.insertName("Subtype", "Image"); |
353 pdfDict.insertInt("Width", bitmap.width()); | 368 pdfDict.insertInt("Width", bitmap.width()); |
354 pdfDict.insertInt("Height", bitmap.height()); | 369 pdfDict.insertInt("Height", bitmap.height()); |
355 if (alpha) { | 370 if (alpha) { |
356 pdfDict.insertName("ColorSpace", "DeviceGray"); | 371 pdfDict.insertName("ColorSpace", "DeviceGray"); |
357 } else if (bitmap.colorType() == kIndex_8_SkColorType) { | 372 } else if (bitmap.colorType() == kIndex_8_SkColorType) { |
358 SkASSERT(1 == pdf_color_component_count(bitmap.colorType())); | 373 SkASSERT(1 == pdf_color_component_count(bitmap.colorType())); |
359 pdfDict.insertObject("ColorSpace", | 374 pdfDict.insertObject("ColorSpace", |
360 make_indexed_color_space(bitmap.getColorTable())); | 375 make_indexed_color_space(bitmap.getColorTable(), |
| 376 bitmap.alphaType())); |
361 } else if (1 == pdf_color_component_count(bitmap.colorType())) { | 377 } else if (1 == pdf_color_component_count(bitmap.colorType())) { |
362 pdfDict.insertName("ColorSpace", "DeviceGray"); | 378 pdfDict.insertName("ColorSpace", "DeviceGray"); |
363 } else { | 379 } else { |
364 pdfDict.insertName("ColorSpace", "DeviceRGB"); | 380 pdfDict.insertName("ColorSpace", "DeviceRGB"); |
365 } | 381 } |
366 if (smask) { | 382 if (smask) { |
367 pdfDict.insertObjRef("SMask", smask); | 383 pdfDict.insertObjRef("SMask", smask); |
368 } | 384 } |
369 pdfDict.insertInt("BitsPerComponent", 8); | 385 pdfDict.insertInt("BitsPerComponent", 8); |
370 pdfDict.insertName("Filter", "FlateDecode"); | 386 pdfDict.insertName("Filter", "FlateDecode"); |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
511 | 527 |
512 sk_sp<SkPDFObject> smask; | 528 sk_sp<SkPDFObject> smask; |
513 if (!image_compute_is_opaque(image.get())) { | 529 if (!image_compute_is_opaque(image.get())) { |
514 smask = sk_make_sp<PDFAlphaBitmap>(image); | 530 smask = sk_make_sp<PDFAlphaBitmap>(image); |
515 } | 531 } |
516 #ifdef SK_PDF_IMAGE_STATS | 532 #ifdef SK_PDF_IMAGE_STATS |
517 gRegularImageObjects.fetch_add(1); | 533 gRegularImageObjects.fetch_add(1); |
518 #endif | 534 #endif |
519 return sk_make_sp<PDFDefaultBitmap>(std::move(image), std::move(smask)); | 535 return sk_make_sp<PDFDefaultBitmap>(std::move(image), std::move(smask)); |
520 } | 536 } |
OLD | NEW |