| 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 |