| 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 "SkBmpStandardCodec.h" | 8 #include "SkBmpStandardCodec.h" |
| 9 #include "SkCodecPriv.h" | 9 #include "SkCodecPriv.h" |
| 10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" |
| 11 #include "SkScanlineDecoder.h" | 11 #include "SkScanlineDecoder.h" |
| 12 #include "SkStream.h" | 12 #include "SkStream.h" |
| 13 | 13 |
| 14 /* | 14 /* |
| 15 * Creates an instance of the decoder | 15 * Creates an instance of the decoder |
| 16 * Called only by NewFromStream | 16 * Called only by NewFromStream |
| 17 */ | 17 */ |
| 18 SkBmpStandardCodec::SkBmpStandardCodec(const SkImageInfo& info, SkStream* stream
, | 18 SkBmpStandardCodec::SkBmpStandardCodec(const SkImageInfo& info, SkStream* stream
, |
| 19 uint16_t bitsPerPixel, uint32_t numColors
, | 19 uint16_t bitsPerPixel, uint32_t numColors
, |
| 20 uint32_t bytesPerColor, uint32_t offset, | 20 uint32_t bytesPerColor, uint32_t offset, |
| 21 SkBmpCodec::RowOrder rowOrder, bool inIco
) | 21 SkBmpCodec::RowOrder rowOrder, bool inIco
) |
| 22 : INHERITED(info, stream, bitsPerPixel, rowOrder) | 22 : INHERITED(info, stream, bitsPerPixel, rowOrder) |
| 23 , fColorTable(NULL) | 23 , fColorTable(nullptr) |
| 24 , fNumColors(this->computeNumColors(numColors)) | 24 , fNumColors(this->computeNumColors(numColors)) |
| 25 , fBytesPerColor(bytesPerColor) | 25 , fBytesPerColor(bytesPerColor) |
| 26 , fOffset(offset) | 26 , fOffset(offset) |
| 27 , fSwizzler(NULL) | 27 , fSwizzler(nullptr) |
| 28 , fSrcBuffer(NULL) | 28 , fSrcBuffer(nullptr) |
| 29 , fInIco(inIco) | 29 , fInIco(inIco) |
| 30 {} | 30 {} |
| 31 | 31 |
| 32 /* | 32 /* |
| 33 * Initiates the bitmap decode | 33 * Initiates the bitmap decode |
| 34 */ | 34 */ |
| 35 SkCodec::Result SkBmpStandardCodec::onGetPixels(const SkImageInfo& dstInfo, | 35 SkCodec::Result SkBmpStandardCodec::onGetPixels(const SkImageInfo& dstInfo, |
| 36 void* dst, size_t dstRowBytes, | 36 void* dst, size_t dstRowBytes, |
| 37 const Options& opts, | 37 const Options& opts, |
| 38 SkPMColor* inputColorPtr, | 38 SkPMColor* inputColorPtr, |
| 39 int* inputColorCount) { | 39 int* inputColorCount) { |
| 40 if (!this->rewindIfNeeded()) { | 40 if (!this->rewindIfNeeded()) { |
| 41 return kCouldNotRewind; | 41 return kCouldNotRewind; |
| 42 } | 42 } |
| 43 if (opts.fSubset) { | 43 if (opts.fSubset) { |
| 44 // Subsets are not supported. | 44 // Subsets are not supported. |
| 45 return kUnimplemented; | 45 return kUnimplemented; |
| 46 } | 46 } |
| 47 if (dstInfo.dimensions() != this->getInfo().dimensions()) { | 47 if (dstInfo.dimensions() != this->getInfo().dimensions()) { |
| 48 SkCodecPrintf("Error: scaling not supported.\n"); | 48 SkCodecPrintf("Error: scaling not supported.\n"); |
| 49 return kInvalidScale; | 49 return kInvalidScale; |
| 50 } | 50 } |
| 51 if (!conversion_possible(dstInfo, this->getInfo())) { | 51 if (!conversion_possible(dstInfo, this->getInfo())) { |
| 52 SkCodecPrintf("Error: cannot convert input type to output type.\n"); | 52 SkCodecPrintf("Error: cannot convert input type to output type.\n"); |
| 53 return kInvalidConversion; | 53 return kInvalidConversion; |
| 54 } | 54 } |
| 55 | 55 |
| 56 // Create the color table if necessary and prepare the stream for decode | 56 // Create the color table if necessary and prepare the stream for decode |
| 57 // Note that if it is non-NULL, inputColorCount will be modified | 57 // Note that if it is non-nullptr, inputColorCount will be modified |
| 58 if (!this->createColorTable(dstInfo.alphaType(), inputColorCount)) { | 58 if (!this->createColorTable(dstInfo.alphaType(), inputColorCount)) { |
| 59 SkCodecPrintf("Error: could not create color table.\n"); | 59 SkCodecPrintf("Error: could not create color table.\n"); |
| 60 return kInvalidInput; | 60 return kInvalidInput; |
| 61 } | 61 } |
| 62 | 62 |
| 63 // Copy the color table to the client if necessary | 63 // Copy the color table to the client if necessary |
| 64 copy_color_table(dstInfo, fColorTable, inputColorPtr, inputColorCount); | 64 copy_color_table(dstInfo, fColorTable, inputColorPtr, inputColorCount); |
| 65 | 65 |
| 66 // Initialize a swizzler if necessary | 66 // Initialize a swizzler if necessary |
| 67 if (!this->initializeSwizzler(dstInfo, opts)) { | 67 if (!this->initializeSwizzler(dstInfo, opts)) { |
| 68 SkCodecPrintf("Error: cannot initialize swizzler.\n"); | 68 SkCodecPrintf("Error: cannot initialize swizzler.\n"); |
| 69 return kInvalidConversion; | 69 return kInvalidConversion; |
| 70 } | 70 } |
| 71 | 71 |
| 72 return this->decode(dstInfo, dst, dstRowBytes, opts); | 72 return this->decode(dstInfo, dst, dstRowBytes, opts); |
| 73 } | 73 } |
| 74 | 74 |
| 75 /* | 75 /* |
| 76 * Process the color table for the bmp input | 76 * Process the color table for the bmp input |
| 77 */ | 77 */ |
| 78 bool SkBmpStandardCodec::createColorTable(SkAlphaType alphaType, int* numColors
) { | 78 bool SkBmpStandardCodec::createColorTable(SkAlphaType alphaType, int* numColors
) { |
| 79 // Allocate memory for color table | 79 // Allocate memory for color table |
| 80 uint32_t colorBytes = 0; | 80 uint32_t colorBytes = 0; |
| 81 SkPMColor colorTable[256]; | 81 SkPMColor colorTable[256]; |
| 82 if (this->bitsPerPixel() <= 8) { | 82 if (this->bitsPerPixel() <= 8) { |
| 83 // Inform the caller of the number of colors | 83 // Inform the caller of the number of colors |
| 84 uint32_t maxColors = 1 << this->bitsPerPixel(); | 84 uint32_t maxColors = 1 << this->bitsPerPixel(); |
| 85 if (NULL != numColors) { | 85 if (nullptr != numColors) { |
| 86 // We set the number of colors to maxColors in order to ensure | 86 // We set the number of colors to maxColors in order to ensure |
| 87 // safe memory accesses. Otherwise, an invalid pixel could | 87 // safe memory accesses. Otherwise, an invalid pixel could |
| 88 // access memory outside of our color table array. | 88 // access memory outside of our color table array. |
| 89 *numColors = maxColors; | 89 *numColors = maxColors; |
| 90 } | 90 } |
| 91 | 91 |
| 92 // Read the color table from the stream | 92 // Read the color table from the stream |
| 93 colorBytes = fNumColors * fBytesPerColor; | 93 colorBytes = fNumColors * fBytesPerColor; |
| 94 SkAutoTDeleteArray<uint8_t> cBuffer(new uint8_t[colorBytes]); | 94 SkAutoTDeleteArray<uint8_t> cBuffer(new uint8_t[colorBytes]); |
| 95 if (stream()->read(cBuffer.get(), colorBytes) != colorBytes) { | 95 if (stream()->read(cBuffer.get(), colorBytes) != colorBytes) { |
| 96 SkCodecPrintf("Error: unable to read color table.\n"); | 96 SkCodecPrintf("Error: unable to read color table.\n"); |
| 97 return false; | 97 return false; |
| 98 } | 98 } |
| 99 | 99 |
| 100 // Choose the proper packing function | 100 // Choose the proper packing function |
| 101 SkPMColor (*packARGB) (uint32_t, uint32_t, uint32_t, uint32_t); | 101 SkPMColor (*packARGB) (uint32_t, uint32_t, uint32_t, uint32_t); |
| 102 switch (alphaType) { | 102 switch (alphaType) { |
| 103 case kOpaque_SkAlphaType: | 103 case kOpaque_SkAlphaType: |
| 104 case kUnpremul_SkAlphaType: | 104 case kUnpremul_SkAlphaType: |
| 105 packARGB = &SkPackARGB32NoCheck; | 105 packARGB = &SkPackARGB32NoCheck; |
| 106 break; | 106 break; |
| 107 case kPremul_SkAlphaType: | 107 case kPremul_SkAlphaType: |
| 108 packARGB = &SkPreMultiplyARGB; | 108 packARGB = &SkPreMultiplyARGB; |
| 109 break; | 109 break; |
| 110 default: | 110 default: |
| 111 // This should not be reached because conversion possible | 111 // This should not be reached because conversion possible |
| 112 // should fail if the alpha type is not one of the above | 112 // should fail if the alpha type is not one of the above |
| 113 // values. | 113 // values. |
| 114 SkASSERT(false); | 114 SkASSERT(false); |
| 115 packARGB = NULL; | 115 packARGB = nullptr; |
| 116 break; | 116 break; |
| 117 } | 117 } |
| 118 | 118 |
| 119 // Fill in the color table | 119 // Fill in the color table |
| 120 uint32_t i = 0; | 120 uint32_t i = 0; |
| 121 for (; i < fNumColors; i++) { | 121 for (; i < fNumColors; i++) { |
| 122 uint8_t blue = get_byte(cBuffer.get(), i*fBytesPerColor); | 122 uint8_t blue = get_byte(cBuffer.get(), i*fBytesPerColor); |
| 123 uint8_t green = get_byte(cBuffer.get(), i*fBytesPerColor + 1); | 123 uint8_t green = get_byte(cBuffer.get(), i*fBytesPerColor + 1); |
| 124 uint8_t red = get_byte(cBuffer.get(), i*fBytesPerColor + 2); | 124 uint8_t red = get_byte(cBuffer.get(), i*fBytesPerColor + 2); |
| 125 uint8_t alpha; | 125 uint8_t alpha; |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 203 return false; | 203 return false; |
| 204 } | 204 } |
| 205 | 205 |
| 206 // Get a pointer to the color table if it exists | 206 // Get a pointer to the color table if it exists |
| 207 const SkPMColor* colorPtr = get_color_ptr(fColorTable.get()); | 207 const SkPMColor* colorPtr = get_color_ptr(fColorTable.get()); |
| 208 | 208 |
| 209 // Create swizzler | 209 // Create swizzler |
| 210 fSwizzler.reset(SkSwizzler::CreateSwizzler(config, | 210 fSwizzler.reset(SkSwizzler::CreateSwizzler(config, |
| 211 colorPtr, dstInfo, opts.fZeroInitialized, this->getInfo())); | 211 colorPtr, dstInfo, opts.fZeroInitialized, this->getInfo())); |
| 212 | 212 |
| 213 if (NULL == fSwizzler.get()) { | 213 if (nullptr == fSwizzler.get()) { |
| 214 return false; | 214 return false; |
| 215 } | 215 } |
| 216 return true; | 216 return true; |
| 217 } | 217 } |
| 218 | 218 |
| 219 /* | 219 /* |
| 220 * Choose a fill for failures due to an incomplete image. We will use zero as | 220 * Choose a fill for failures due to an incomplete image. We will use zero as |
| 221 * the default palette index, black for opaque images, and transparent for | 221 * the default palette index, black for opaque images, and transparent for |
| 222 * non-opaque images. | 222 * non-opaque images. |
| 223 */ | 223 */ |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 328 uint32_t alphaBit = | 328 uint32_t alphaBit = |
| 329 (fSrcBuffer.get()[quotient] >> shift) & 0x1; | 329 (fSrcBuffer.get()[quotient] >> shift) & 0x1; |
| 330 dstRow[x] &= alphaBit - 1; | 330 dstRow[x] &= alphaBit - 1; |
| 331 } | 331 } |
| 332 } | 332 } |
| 333 } | 333 } |
| 334 | 334 |
| 335 // Finished decoding the entire image | 335 // Finished decoding the entire image |
| 336 return kSuccess; | 336 return kSuccess; |
| 337 } | 337 } |
| OLD | NEW |