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 |