OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
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 "SkImageDecoder.h" | 9 #include "SkImageDecoder.h" |
10 #include "SkStream.h" | 10 #include "SkStream.h" |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
120 // promote the sum to 64-bits to avoid overflow | 120 // promote the sum to 64-bits to avoid overflow |
121 // Check that buffer is large enough to read image data | 121 // Check that buffer is large enough to read image data |
122 if (offset > length || size > length || ((uint64_t)offset + size) > length)
{ | 122 if (offset > length || size > length || ((uint64_t)offset + size) > length)
{ |
123 return kFailure; | 123 return kFailure; |
124 } | 124 } |
125 | 125 |
126 // Check to see if this is a PNG image inside the ICO | 126 // Check to see if this is a PNG image inside the ICO |
127 { | 127 { |
128 SkMemoryStream subStream(buf + offset, size, false); | 128 SkMemoryStream subStream(buf + offset, size, false); |
129 SkAutoTDelete<SkImageDecoder> otherDecoder(SkImageDecoder::Factory(&subS
tream)); | 129 SkAutoTDelete<SkImageDecoder> otherDecoder(SkImageDecoder::Factory(&subS
tream)); |
130 if (otherDecoder.get() != NULL) { | 130 if (otherDecoder.get() != nullptr) { |
131 // Disallow nesting ICO files within one another | 131 // Disallow nesting ICO files within one another |
132 // FIXME: Can ICO files contain other formats besides PNG? | 132 // FIXME: Can ICO files contain other formats besides PNG? |
133 if (otherDecoder->getFormat() == SkImageDecoder::kICO_Format) { | 133 if (otherDecoder->getFormat() == SkImageDecoder::kICO_Format) { |
134 return kFailure; | 134 return kFailure; |
135 } | 135 } |
136 // Set fields on the other decoder to be the same as this one. | 136 // Set fields on the other decoder to be the same as this one. |
137 this->copyFieldsToOther(otherDecoder.get()); | 137 this->copyFieldsToOther(otherDecoder.get()); |
138 const Result result = otherDecoder->decode(&subStream, bm, this->get
DefaultPref(), | 138 const Result result = otherDecoder->decode(&subStream, bm, this->get
DefaultPref(), |
139 mode); | 139 mode); |
140 // FIXME: Should we just return result here? Is it possible that dat
a that looked like | 140 // FIXME: Should we just return result here? Is it possible that dat
a that looked like |
(...skipping 19 matching lines...) Expand all Loading... |
160 } | 160 } |
161 | 161 |
162 // Check that buffer is large enough to read the bit depth | 162 // Check that buffer is large enough to read the bit depth |
163 if (length < offset + 16) { | 163 if (length < offset + 16) { |
164 return kFailure; | 164 return kFailure; |
165 } | 165 } |
166 int bitCount = read2Bytes(buf, offset+14); | 166 int bitCount = read2Bytes(buf, offset+14); |
167 | 167 |
168 void (*placePixel)(const int pixelNo, const unsigned char* buf, | 168 void (*placePixel)(const int pixelNo, const unsigned char* buf, |
169 const int xorOffset, int& x, int y, const int w, | 169 const int xorOffset, int& x, int y, const int w, |
170 SkBitmap* bm, int alphaByte, int m, int shift, SkPMColor* colors) = NULL
; | 170 SkBitmap* bm, int alphaByte, int m, int shift, SkPMColor* colors) = null
ptr; |
171 switch (bitCount) | 171 switch (bitCount) |
172 { | 172 { |
173 case 1: | 173 case 1: |
174 placePixel = &editPixelBit1; | 174 placePixel = &editPixelBit1; |
175 colorCount = 2; | 175 colorCount = 2; |
176 break; | 176 break; |
177 case 4: | 177 case 4: |
178 placePixel = &editPixelBit4; | 178 placePixel = &editPixelBit4; |
179 colorCount = 16; | 179 colorCount = 16; |
180 break; | 180 break; |
(...skipping 24 matching lines...) Expand all Loading... |
205 | 205 |
206 int begin = SkToInt(offset + 40); | 206 int begin = SkToInt(offset + 40); |
207 // Check that the buffer is large enough to read the color table | 207 // Check that the buffer is large enough to read the color table |
208 // For bmp-in-icos, there should be 4 bytes per color | 208 // For bmp-in-icos, there should be 4 bytes per color |
209 if (length < (size_t) (begin + 4*colorCount)) { | 209 if (length < (size_t) (begin + 4*colorCount)) { |
210 return kFailure; | 210 return kFailure; |
211 } | 211 } |
212 | 212 |
213 //this array represents the colortable | 213 //this array represents the colortable |
214 //if i allow other types of bitmaps, it may actually be used as a part of th
e bitmap | 214 //if i allow other types of bitmaps, it may actually be used as a part of th
e bitmap |
215 SkPMColor* colors = NULL; | 215 SkPMColor* colors = nullptr; |
216 int blue, green, red; | 216 int blue, green, red; |
217 if (colorCount) | 217 if (colorCount) |
218 { | 218 { |
219 colors = new SkPMColor[colorCount]; | 219 colors = new SkPMColor[colorCount]; |
220 for (int j = 0; j < colorCount; j++) | 220 for (int j = 0; j < colorCount; j++) |
221 { | 221 { |
222 //should this be a function - maybe a #define? | 222 //should this be a function - maybe a #define? |
223 blue = readByte(buf, begin + 4*j); | 223 blue = readByte(buf, begin + 4*j); |
224 green = readByte(buf, begin + 4*j + 1); | 224 green = readByte(buf, begin + 4*j + 1); |
225 red = readByte(buf, begin + 4*j + 2); | 225 red = readByte(buf, begin + 4*j + 2); |
(...skipping 19 matching lines...) Expand all Loading... |
245 //if the andbitmap (mask) is all zeroes, then we can easily do an index bitm
ap | 245 //if the andbitmap (mask) is all zeroes, then we can easily do an index bitm
ap |
246 //however, with small images with large colortables, maybe it's better to st
ill do argb_8888 | 246 //however, with small images with large colortables, maybe it's better to st
ill do argb_8888 |
247 | 247 |
248 bm->setInfo(SkImageInfo::MakeN32Premul(w, h), calculateRowBytesFor8888(w, bi
tCount)); | 248 bm->setInfo(SkImageInfo::MakeN32Premul(w, h), calculateRowBytesFor8888(w, bi
tCount)); |
249 | 249 |
250 if (SkImageDecoder::kDecodeBounds_Mode == mode) { | 250 if (SkImageDecoder::kDecodeBounds_Mode == mode) { |
251 delete[] colors; | 251 delete[] colors; |
252 return kSuccess; | 252 return kSuccess; |
253 } | 253 } |
254 | 254 |
255 if (!this->allocPixelRef(bm, NULL)) | 255 if (!this->allocPixelRef(bm, nullptr)) |
256 { | 256 { |
257 delete[] colors; | 257 delete[] colors; |
258 return kFailure; | 258 return kFailure; |
259 } | 259 } |
260 | 260 |
261 // The AND mask is a 1-bit alpha mask for each pixel that comes after the | 261 // The AND mask is a 1-bit alpha mask for each pixel that comes after the |
262 // XOR mask in the bmp. If we check that the largest AND offset is safe, | 262 // XOR mask in the bmp. If we check that the largest AND offset is safe, |
263 // it should mean all other buffer accesses will be at smaller indices and | 263 // it should mean all other buffer accesses will be at smaller indices and |
264 // will therefore be safe. | 264 // will therefore be safe. |
265 size_t maxAndOffset = andOffset + ((andLineWidth*(h-1)+(w-1)) >> 3); | 265 size_t maxAndOffset = andOffset + ((andLineWidth*(h-1)+(w-1)) >> 3); |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
430 } | 430 } |
431 int reserved = read2Bytes(buf, 0); | 431 int reserved = read2Bytes(buf, 0); |
432 int type = read2Bytes(buf, 2); | 432 int type = read2Bytes(buf, 2); |
433 return 0 == reserved && 1 == type; | 433 return 0 == reserved && 1 == type; |
434 } | 434 } |
435 | 435 |
436 static SkImageDecoder* sk_libico_dfactory(SkStreamRewindable* stream) { | 436 static SkImageDecoder* sk_libico_dfactory(SkStreamRewindable* stream) { |
437 if (is_ico(stream)) { | 437 if (is_ico(stream)) { |
438 return new SkICOImageDecoder; | 438 return new SkICOImageDecoder; |
439 } | 439 } |
440 return NULL; | 440 return nullptr; |
441 } | 441 } |
442 | 442 |
443 static SkImageDecoder_DecodeReg gReg(sk_libico_dfactory); | 443 static SkImageDecoder_DecodeReg gReg(sk_libico_dfactory); |
444 | 444 |
445 static SkImageDecoder::Format get_format_ico(SkStreamRewindable* stream) { | 445 static SkImageDecoder::Format get_format_ico(SkStreamRewindable* stream) { |
446 if (is_ico(stream)) { | 446 if (is_ico(stream)) { |
447 return SkImageDecoder::kICO_Format; | 447 return SkImageDecoder::kICO_Format; |
448 } | 448 } |
449 return SkImageDecoder::kUnknown_Format; | 449 return SkImageDecoder::kUnknown_Format; |
450 } | 450 } |
451 | 451 |
452 static SkImageDecoder_FormatReg gFormatReg(get_format_ico); | 452 static SkImageDecoder_FormatReg gFormatReg(get_format_ico); |
OLD | NEW |