| 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 "SkBmpCodec.h" | 8 #include "SkBmpCodec.h" |
| 9 #include "SkBmpMaskCodec.h" | 9 #include "SkBmpMaskCodec.h" |
| 10 #include "SkBmpRLECodec.h" | 10 #include "SkBmpRLECodec.h" |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 106 // check that it is valid in the RLE case. | 106 // check that it is valid in the RLE case. |
| 107 uint32_t totalBytes; | 107 uint32_t totalBytes; |
| 108 // The offset from the start of the file where the pixel data begins | 108 // The offset from the start of the file where the pixel data begins |
| 109 uint32_t offset; | 109 uint32_t offset; |
| 110 // The size of the second (info) header in bytes | 110 // The size of the second (info) header in bytes |
| 111 uint32_t infoBytes; | 111 uint32_t infoBytes; |
| 112 | 112 |
| 113 // Bmps embedded in Icos skip the first Bmp header | 113 // Bmps embedded in Icos skip the first Bmp header |
| 114 if (!inIco) { | 114 if (!inIco) { |
| 115 // Read the first header and the size of the second header | 115 // Read the first header and the size of the second header |
| 116 SkAutoTDeleteArray<uint8_t> hBuffer( | 116 SkAutoTDeleteArray<uint8_t> hBuffer(new uint8_t[kBmpHeaderBytesPlusFour]
); |
| 117 SkNEW_ARRAY(uint8_t, kBmpHeaderBytesPlusFour)); | |
| 118 if (stream->read(hBuffer.get(), kBmpHeaderBytesPlusFour) != | 117 if (stream->read(hBuffer.get(), kBmpHeaderBytesPlusFour) != |
| 119 kBmpHeaderBytesPlusFour) { | 118 kBmpHeaderBytesPlusFour) { |
| 120 SkCodecPrintf("Error: unable to read first bitmap header.\n"); | 119 SkCodecPrintf("Error: unable to read first bitmap header.\n"); |
| 121 return false; | 120 return false; |
| 122 } | 121 } |
| 123 | 122 |
| 124 totalBytes = get_int(hBuffer.get(), 2); | 123 totalBytes = get_int(hBuffer.get(), 2); |
| 125 offset = get_int(hBuffer.get(), 10); | 124 offset = get_int(hBuffer.get(), 10); |
| 126 if (offset < kBmpHeaderBytes + kBmpOS2V1Bytes) { | 125 if (offset < kBmpHeaderBytes + kBmpOS2V1Bytes) { |
| 127 SkCodecPrintf("Error: invalid starting location for pixel data\n"); | 126 SkCodecPrintf("Error: invalid starting location for pixel data\n"); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 141 // use RLE. If the compression field is incorrectly signaled as RLE, | 140 // use RLE. If the compression field is incorrectly signaled as RLE, |
| 142 // we will catch this and signal an error below. | 141 // we will catch this and signal an error below. |
| 143 totalBytes = 0; | 142 totalBytes = 0; |
| 144 | 143 |
| 145 // Bmps in Ico cannot specify an offset. We will always assume that | 144 // Bmps in Ico cannot specify an offset. We will always assume that |
| 146 // pixel data begins immediately after the color table. This value | 145 // pixel data begins immediately after the color table. This value |
| 147 // will be corrected below. | 146 // will be corrected below. |
| 148 offset = 0; | 147 offset = 0; |
| 149 | 148 |
| 150 // Read the size of the second header | 149 // Read the size of the second header |
| 151 SkAutoTDeleteArray<uint8_t> hBuffer( | 150 SkAutoTDeleteArray<uint8_t> hBuffer(new uint8_t[4]); |
| 152 SkNEW_ARRAY(uint8_t, 4)); | |
| 153 if (stream->read(hBuffer.get(), 4) != 4) { | 151 if (stream->read(hBuffer.get(), 4) != 4) { |
| 154 SkCodecPrintf("Error: unable to read size of second bitmap header.\n
"); | 152 SkCodecPrintf("Error: unable to read size of second bitmap header.\n
"); |
| 155 return false; | 153 return false; |
| 156 } | 154 } |
| 157 infoBytes = get_int(hBuffer.get(), 0); | 155 infoBytes = get_int(hBuffer.get(), 0); |
| 158 if (infoBytes < kBmpOS2V1Bytes) { | 156 if (infoBytes < kBmpOS2V1Bytes) { |
| 159 SkCodecPrintf("Error: invalid second header size.\n"); | 157 SkCodecPrintf("Error: invalid second header size.\n"); |
| 160 return false; | 158 return false; |
| 161 } | 159 } |
| 162 } | 160 } |
| 163 | 161 |
| 164 // We already read the first four bytes of the info header to get the size | 162 // We already read the first four bytes of the info header to get the size |
| 165 const uint32_t infoBytesRemaining = infoBytes - 4; | 163 const uint32_t infoBytesRemaining = infoBytes - 4; |
| 166 | 164 |
| 167 // Read the second header | 165 // Read the second header |
| 168 SkAutoTDeleteArray<uint8_t> iBuffer( | 166 SkAutoTDeleteArray<uint8_t> iBuffer(new uint8_t[infoBytesRemaining]); |
| 169 SkNEW_ARRAY(uint8_t, infoBytesRemaining)); | |
| 170 if (stream->read(iBuffer.get(), infoBytesRemaining) != infoBytesRemaining) { | 167 if (stream->read(iBuffer.get(), infoBytesRemaining) != infoBytesRemaining) { |
| 171 SkCodecPrintf("Error: unable to read second bitmap header.\n"); | 168 SkCodecPrintf("Error: unable to read second bitmap header.\n"); |
| 172 return false; | 169 return false; |
| 173 } | 170 } |
| 174 | 171 |
| 175 // The number of bits used per pixel in the pixel data | 172 // The number of bits used per pixel in the pixel data |
| 176 uint16_t bitsPerPixel; | 173 uint16_t bitsPerPixel; |
| 177 | 174 |
| 178 // The compression method for the pixel data | 175 // The compression method for the pixel data |
| 179 uint32_t compression = kNone_BmpCompressionMethod; | 176 uint32_t compression = kNone_BmpCompressionMethod; |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 306 } | 303 } |
| 307 inputFormat = kRLE_BmpInputFormat; | 304 inputFormat = kRLE_BmpInputFormat; |
| 308 break; | 305 break; |
| 309 case kAlphaBitMasks_BmpCompressionMethod: | 306 case kAlphaBitMasks_BmpCompressionMethod: |
| 310 case kBitMasks_BmpCompressionMethod: | 307 case kBitMasks_BmpCompressionMethod: |
| 311 // Load the masks | 308 // Load the masks |
| 312 inputFormat = kBitMask_BmpInputFormat; | 309 inputFormat = kBitMask_BmpInputFormat; |
| 313 switch (headerType) { | 310 switch (headerType) { |
| 314 case kInfoV1_BmpHeaderType: { | 311 case kInfoV1_BmpHeaderType: { |
| 315 // The V1 header stores the bit masks after the header | 312 // The V1 header stores the bit masks after the header |
| 316 SkAutoTDeleteArray<uint8_t> mBuffer( | 313 SkAutoTDeleteArray<uint8_t> mBuffer(new uint8_t[kBmpMaskByte
s]); |
| 317 SkNEW_ARRAY(uint8_t, kBmpMaskBytes)); | |
| 318 if (stream->read(mBuffer.get(), kBmpMaskBytes) != | 314 if (stream->read(mBuffer.get(), kBmpMaskBytes) != |
| 319 kBmpMaskBytes) { | 315 kBmpMaskBytes) { |
| 320 SkCodecPrintf("Error: unable to read bit inputMasks.\n")
; | 316 SkCodecPrintf("Error: unable to read bit inputMasks.\n")
; |
| 321 return false; | 317 return false; |
| 322 } | 318 } |
| 323 maskBytes = kBmpMaskBytes; | 319 maskBytes = kBmpMaskBytes; |
| 324 inputMasks.red = get_int(mBuffer.get(), 0); | 320 inputMasks.red = get_int(mBuffer.get(), 0); |
| 325 inputMasks.green = get_int(mBuffer.get(), 4); | 321 inputMasks.green = get_int(mBuffer.get(), 4); |
| 326 inputMasks.blue = get_int(mBuffer.get(), 8); | 322 inputMasks.blue = get_int(mBuffer.get(), 8); |
| 327 break; | 323 break; |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 465 } | 461 } |
| 466 | 462 |
| 467 if (codecOut) { | 463 if (codecOut) { |
| 468 // Set the image info | 464 // Set the image info |
| 469 const SkImageInfo& imageInfo = SkImageInfo::Make(width, height, | 465 const SkImageInfo& imageInfo = SkImageInfo::Make(width, height, |
| 470 colorType, alphaType); | 466 colorType, alphaType); |
| 471 | 467 |
| 472 // Return the codec | 468 // Return the codec |
| 473 switch (inputFormat) { | 469 switch (inputFormat) { |
| 474 case kStandard_BmpInputFormat: | 470 case kStandard_BmpInputFormat: |
| 475 *codecOut = SkNEW_ARGS(SkBmpStandardCodec, (imageInfo, stream, | 471 *codecOut = |
| 476 bitsPerPixel, numColors, bytesPerColor, | 472 new SkBmpStandardCodec(imageInfo, stream, bitsPerPixel,
numColors, |
| 477 offset - bytesRead, rowOrder, inIco)); | 473 bytesPerColor, offset - bytesRead
, rowOrder, inIco); |
| 478 return true; | 474 return true; |
| 479 case kBitMask_BmpInputFormat: | 475 case kBitMask_BmpInputFormat: |
| 480 // Bmp-in-Ico must be standard mode | 476 // Bmp-in-Ico must be standard mode |
| 481 if (inIco) { | 477 if (inIco) { |
| 482 SkCodecPrintf("Error: Icos may not use bit mask format.\n"); | 478 SkCodecPrintf("Error: Icos may not use bit mask format.\n"); |
| 483 return false; | 479 return false; |
| 484 } | 480 } |
| 485 // Skip to the start of the pixel array. | 481 // Skip to the start of the pixel array. |
| 486 // We can do this here because there is no color table to read | 482 // We can do this here because there is no color table to read |
| 487 // in bit mask mode. | 483 // in bit mask mode. |
| 488 if (stream->skip(offset - bytesRead) != offset - bytesRead) { | 484 if (stream->skip(offset - bytesRead) != offset - bytesRead) { |
| 489 SkCodecPrintf("Error: unable to skip to image data.\n"); | 485 SkCodecPrintf("Error: unable to skip to image data.\n"); |
| 490 return false; | 486 return false; |
| 491 } | 487 } |
| 492 | 488 |
| 493 *codecOut = SkNEW_ARGS(SkBmpMaskCodec, (imageInfo, stream, | 489 *codecOut = new SkBmpMaskCodec(imageInfo, stream, bitsPerPixel,
masks.detach(), |
| 494 bitsPerPixel, masks.detach(), rowOrder)); | 490 rowOrder); |
| 495 return true; | 491 return true; |
| 496 case kRLE_BmpInputFormat: | 492 case kRLE_BmpInputFormat: |
| 497 // Bmp-in-Ico must be standard mode | 493 // Bmp-in-Ico must be standard mode |
| 498 // When inIco is true, this line cannot be reached, since we | 494 // When inIco is true, this line cannot be reached, since we |
| 499 // require that RLE Bmps have a valid number of totalBytes, and | 495 // require that RLE Bmps have a valid number of totalBytes, and |
| 500 // Icos skip the header that contains totalBytes. | 496 // Icos skip the header that contains totalBytes. |
| 501 SkASSERT(!inIco); | 497 SkASSERT(!inIco); |
| 502 *codecOut = SkNEW_ARGS(SkBmpRLECodec, ( | 498 *codecOut = |
| 503 imageInfo, stream, bitsPerPixel, numColors, | 499 new SkBmpRLECodec(imageInfo, stream, bitsPerPixel, numCo
lors, bytesPerColor, |
| 504 bytesPerColor, offset - bytesRead, rowOrder, RLEBytes)); | 500 offset - bytesRead, rowOrder, RLEBytes
); |
| 505 return true; | 501 return true; |
| 506 default: | 502 default: |
| 507 SkASSERT(false); | 503 SkASSERT(false); |
| 508 return false; | 504 return false; |
| 509 } | 505 } |
| 510 } | 506 } |
| 511 | 507 |
| 512 return true; | 508 return true; |
| 513 } | 509 } |
| 514 | 510 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 556 */ | 552 */ |
| 557 uint32_t SkBmpCodec::computeNumColors(uint32_t numColors) { | 553 uint32_t SkBmpCodec::computeNumColors(uint32_t numColors) { |
| 558 // Zero is a default for maxColors | 554 // Zero is a default for maxColors |
| 559 // Also set numColors to maxColors when it is too large | 555 // Also set numColors to maxColors when it is too large |
| 560 uint32_t maxColors = 1 << fBitsPerPixel; | 556 uint32_t maxColors = 1 << fBitsPerPixel; |
| 561 if (numColors == 0 || numColors >= maxColors) { | 557 if (numColors == 0 || numColors >= maxColors) { |
| 562 return maxColors; | 558 return maxColors; |
| 563 } | 559 } |
| 564 return numColors; | 560 return numColors; |
| 565 } | 561 } |
| OLD | NEW |