| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2006 Apple Computer, Inc. | 2 * Copyright (C) 2006 Apple Computer, Inc. |
| 3 * | 3 * |
| 4 * Portions are Copyright (C) 2001-6 mozilla.org | 4 * Portions are Copyright (C) 2001-6 mozilla.org |
| 5 * | 5 * |
| 6 * Other contributors: | 6 * Other contributors: |
| 7 * Stuart Parmenter <stuart@mozilla.com> | 7 * Stuart Parmenter <stuart@mozilla.com> |
| 8 * | 8 * |
| 9 * This library is free software; you can redistribute it and/or | 9 * This library is free software; you can redistribute it and/or |
| 10 * modify it under the terms of the GNU Lesser General Public | 10 * modify it under the terms of the GNU Lesser General Public |
| (...skipping 21 matching lines...) Expand all Loading... |
| 32 * deletingthe provisions above and replace them with the notice and | 32 * deletingthe provisions above and replace them with the notice and |
| 33 * other provisions required by the MPL or the GPL, as the case may be. | 33 * other provisions required by the MPL or the GPL, as the case may be. |
| 34 * If you do not delete the provisions above, a recipient may use your | 34 * If you do not delete the provisions above, a recipient may use your |
| 35 * version of this file under any of the LGPL, the MPL or the GPL. | 35 * version of this file under any of the LGPL, the MPL or the GPL. |
| 36 */ | 36 */ |
| 37 | 37 |
| 38 #include "platform/image-decoders/jpeg/JPEGImageDecoder.h" | 38 #include "platform/image-decoders/jpeg/JPEGImageDecoder.h" |
| 39 | 39 |
| 40 #include <memory> | 40 #include <memory> |
| 41 #include "platform/instrumentation/PlatformInstrumentation.h" | 41 #include "platform/instrumentation/PlatformInstrumentation.h" |
| 42 #include "third_party/skia/include/core/SkImageInfo.h" |
| 42 #include "wtf/PtrUtil.h" | 43 #include "wtf/PtrUtil.h" |
| 43 | 44 |
| 44 extern "C" { | |
| 45 #include <stdio.h> // jpeglib.h needs stdio FILE. | |
| 46 #include "jpeglib.h" | |
| 47 #include "iccjpeg.h" | |
| 48 #include <setjmp.h> | |
| 49 } | |
| 50 | |
| 51 #if CPU(BIG_ENDIAN) || CPU(MIDDLE_ENDIAN) | |
| 52 #error Blink assumes a little-endian target. | |
| 53 #endif | |
| 54 | |
| 55 #if defined(JCS_ALPHA_EXTENSIONS) | |
| 56 #define TURBO_JPEG_RGB_SWIZZLE | |
| 57 #if SK_B32_SHIFT // Output little-endian RGBA pixels (Android). | |
| 58 inline J_COLOR_SPACE rgbOutputColorSpace() { | |
| 59 return JCS_EXT_RGBA; | |
| 60 } | |
| 61 #else // Output little-endian BGRA pixels. | |
| 62 inline J_COLOR_SPACE rgbOutputColorSpace() { | |
| 63 return JCS_EXT_BGRA; | |
| 64 } | |
| 65 #endif | |
| 66 inline bool turboSwizzled(J_COLOR_SPACE colorSpace) { | |
| 67 return colorSpace == JCS_EXT_RGBA || colorSpace == JCS_EXT_BGRA; | |
| 68 } | |
| 69 #else | |
| 70 inline J_COLOR_SPACE rgbOutputColorSpace() { | |
| 71 return JCS_RGB; | |
| 72 } | |
| 73 #endif | |
| 74 | |
| 75 namespace { | 45 namespace { |
| 76 | 46 |
| 77 const int exifMarker = JPEG_APP0 + 1; | |
| 78 | |
| 79 // JPEG only supports a denominator of 8. | 47 // JPEG only supports a denominator of 8. |
| 80 const unsigned scaleDenominator = 8; | 48 const unsigned scaleDenominator = 8; |
| 81 | 49 |
| 82 } // namespace | 50 } // namespace |
| 83 | 51 |
| 84 namespace blink { | 52 namespace blink { |
| 85 | 53 |
| 86 struct decoder_error_mgr { | |
| 87 DISALLOW_NEW(); | |
| 88 struct jpeg_error_mgr pub; // "public" fields for IJG library | |
| 89 int num_corrupt_warnings; // Counts corrupt warning messages | |
| 90 jmp_buf setjmp_buffer; // For handling catastropic errors | |
| 91 }; | |
| 92 | |
| 93 struct decoder_source_mgr { | |
| 94 DISALLOW_NEW(); | |
| 95 struct jpeg_source_mgr pub; // "public" fields for IJG library | |
| 96 JPEGImageReader* reader; | |
| 97 }; | |
| 98 | |
| 99 enum jstate { | |
| 100 JPEG_HEADER, // Reading JFIF headers | |
| 101 JPEG_START_DECOMPRESS, | |
| 102 JPEG_DECOMPRESS_PROGRESSIVE, // Output progressive pixels | |
| 103 JPEG_DECOMPRESS_SEQUENTIAL, // Output sequential pixels | |
| 104 JPEG_DONE | |
| 105 }; | |
| 106 | |
| 107 enum yuv_subsampling { | |
| 108 YUV_UNKNOWN, | |
| 109 YUV_410, | |
| 110 YUV_411, | |
| 111 YUV_420, | |
| 112 YUV_422, | |
| 113 YUV_440, | |
| 114 YUV_444 | |
| 115 }; | |
| 116 | |
| 117 void init_source(j_decompress_ptr jd); | |
| 118 boolean fill_input_buffer(j_decompress_ptr jd); | |
| 119 void skip_input_data(j_decompress_ptr jd, long num_bytes); | |
| 120 void term_source(j_decompress_ptr jd); | |
| 121 void error_exit(j_common_ptr cinfo); | |
| 122 void emit_message(j_common_ptr cinfo, int msg_level); | |
| 123 | |
| 124 static unsigned readUint16(JOCTET* data, bool isBigEndian) { | |
| 125 if (isBigEndian) | |
| 126 return (GETJOCTET(data[0]) << 8) | GETJOCTET(data[1]); | |
| 127 return (GETJOCTET(data[1]) << 8) | GETJOCTET(data[0]); | |
| 128 } | |
| 129 | |
| 130 static unsigned readUint32(JOCTET* data, bool isBigEndian) { | |
| 131 if (isBigEndian) | |
| 132 return (GETJOCTET(data[0]) << 24) | (GETJOCTET(data[1]) << 16) | | |
| 133 (GETJOCTET(data[2]) << 8) | GETJOCTET(data[3]); | |
| 134 return (GETJOCTET(data[3]) << 24) | (GETJOCTET(data[2]) << 16) | | |
| 135 (GETJOCTET(data[1]) << 8) | GETJOCTET(data[0]); | |
| 136 } | |
| 137 | |
| 138 static bool checkExifHeader(jpeg_saved_marker_ptr marker, | |
| 139 bool& isBigEndian, | |
| 140 unsigned& ifdOffset) { | |
| 141 // For exif data, the APP1 block is followed by 'E', 'x', 'i', 'f', '\0', | |
| 142 // then a fill byte, and then a tiff file that contains the metadata. | |
| 143 // A tiff file starts with 'I', 'I' (intel / little endian byte order) or | |
| 144 // 'M', 'M' (motorola / big endian byte order), followed by (uint16_t)42, | |
| 145 // followed by an uint32_t with the offset to the tag block, relative to the | |
| 146 // tiff file start. | |
| 147 const unsigned exifHeaderSize = 14; | |
| 148 if (!(marker->marker == exifMarker && marker->data_length >= exifHeaderSize && | |
| 149 marker->data[0] == 'E' && marker->data[1] == 'x' && | |
| 150 marker->data[2] == 'i' && marker->data[3] == 'f' && | |
| 151 marker->data[4] == '\0' | |
| 152 // data[5] is a fill byte | |
| 153 && ((marker->data[6] == 'I' && marker->data[7] == 'I') || | |
| 154 (marker->data[6] == 'M' && marker->data[7] == 'M')))) | |
| 155 return false; | |
| 156 | |
| 157 isBigEndian = marker->data[6] == 'M'; | |
| 158 if (readUint16(marker->data + 8, isBigEndian) != 42) | |
| 159 return false; | |
| 160 | |
| 161 ifdOffset = readUint32(marker->data + 10, isBigEndian); | |
| 162 return true; | |
| 163 } | |
| 164 | |
| 165 static ImageOrientation readImageOrientation(jpeg_decompress_struct* info) { | |
| 166 // The JPEG decoder looks at EXIF metadata. | |
| 167 // FIXME: Possibly implement XMP and IPTC support. | |
| 168 const unsigned orientationTag = 0x112; | |
| 169 const unsigned shortType = 3; | |
| 170 for (jpeg_saved_marker_ptr marker = info->marker_list; marker; | |
| 171 marker = marker->next) { | |
| 172 bool isBigEndian; | |
| 173 unsigned ifdOffset; | |
| 174 if (!checkExifHeader(marker, isBigEndian, ifdOffset)) | |
| 175 continue; | |
| 176 const unsigned offsetToTiffData = | |
| 177 6; // Account for 'Exif\0<fill byte>' header. | |
| 178 if (marker->data_length < offsetToTiffData || | |
| 179 ifdOffset >= marker->data_length - offsetToTiffData) | |
| 180 continue; | |
| 181 ifdOffset += offsetToTiffData; | |
| 182 | |
| 183 // The jpeg exif container format contains a tiff block for metadata. | |
| 184 // A tiff image file directory (ifd) consists of a uint16_t describing | |
| 185 // the number of ifd entries, followed by that many entries. | |
| 186 // When touching this code, it's useful to look at the tiff spec: | |
| 187 // http://partners.adobe.com/public/developer/en/tiff/TIFF6.pdf | |
| 188 JOCTET* ifd = marker->data + ifdOffset; | |
| 189 JOCTET* end = marker->data + marker->data_length; | |
| 190 if (end - ifd < 2) | |
| 191 continue; | |
| 192 unsigned tagCount = readUint16(ifd, isBigEndian); | |
| 193 ifd += 2; // Skip over the uint16 that was just read. | |
| 194 | |
| 195 // Every ifd entry is 2 bytes of tag, 2 bytes of contents datatype, | |
| 196 // 4 bytes of number-of-elements, and 4 bytes of either offset to the | |
| 197 // tag data, or if the data is small enough, the inlined data itself. | |
| 198 const int ifdEntrySize = 12; | |
| 199 for (unsigned i = 0; i < tagCount && end - ifd >= ifdEntrySize; | |
| 200 ++i, ifd += ifdEntrySize) { | |
| 201 unsigned tag = readUint16(ifd, isBigEndian); | |
| 202 unsigned type = readUint16(ifd + 2, isBigEndian); | |
| 203 unsigned count = readUint32(ifd + 4, isBigEndian); | |
| 204 if (tag == orientationTag && type == shortType && count == 1) | |
| 205 return ImageOrientation::fromEXIFValue( | |
| 206 readUint16(ifd + 8, isBigEndian)); | |
| 207 } | |
| 208 } | |
| 209 | |
| 210 return ImageOrientation(); | |
| 211 } | |
| 212 | |
| 213 static IntSize computeYUVSize(const jpeg_decompress_struct* info, | |
| 214 int component) { | |
| 215 return IntSize(info->cur_comp_info[component]->downsampled_width, | |
| 216 info->cur_comp_info[component]->downsampled_height); | |
| 217 } | |
| 218 | |
| 219 static size_t computeYUVWidthBytes(const jpeg_decompress_struct* info, | |
| 220 int component) { | |
| 221 return info->cur_comp_info[component]->width_in_blocks * DCTSIZE; | |
| 222 } | |
| 223 | |
| 224 static yuv_subsampling yuvSubsampling(const jpeg_decompress_struct& info) { | |
| 225 if ((DCTSIZE == 8) && (info.num_components == 3) && (info.scale_denom <= 8) && | |
| 226 (info.cur_comp_info[0]) && (info.cur_comp_info[1]) && | |
| 227 (info.cur_comp_info[2]) && (info.cur_comp_info[1]->h_samp_factor == 1) && | |
| 228 (info.cur_comp_info[1]->v_samp_factor == 1) && | |
| 229 (info.cur_comp_info[2]->h_samp_factor == 1) && | |
| 230 (info.cur_comp_info[2]->v_samp_factor == 1)) { | |
| 231 int h = info.cur_comp_info[0]->h_samp_factor; | |
| 232 int v = info.cur_comp_info[0]->v_samp_factor; | |
| 233 // 4:4:4 : (h == 1) && (v == 1) | |
| 234 // 4:4:0 : (h == 1) && (v == 2) | |
| 235 // 4:2:2 : (h == 2) && (v == 1) | |
| 236 // 4:2:0 : (h == 2) && (v == 2) | |
| 237 // 4:1:1 : (h == 4) && (v == 1) | |
| 238 // 4:1:0 : (h == 4) && (v == 2) | |
| 239 if (v == 1) { | |
| 240 switch (h) { | |
| 241 case 1: | |
| 242 return YUV_444; | |
| 243 case 2: | |
| 244 return YUV_422; | |
| 245 case 4: | |
| 246 return YUV_411; | |
| 247 default: | |
| 248 break; | |
| 249 } | |
| 250 } else if (v == 2) { | |
| 251 switch (h) { | |
| 252 case 1: | |
| 253 return YUV_440; | |
| 254 case 2: | |
| 255 return YUV_420; | |
| 256 case 4: | |
| 257 return YUV_410; | |
| 258 default: | |
| 259 break; | |
| 260 } | |
| 261 } | |
| 262 } | |
| 263 | |
| 264 return YUV_UNKNOWN; | |
| 265 } | |
| 266 | |
| 267 static void progressMonitor(j_common_ptr info) { | |
| 268 int scan = ((j_decompress_ptr)info)->input_scan_number; | |
| 269 // Progressive images with a very large number of scans can cause the | |
| 270 // decoder to hang. Here we use the progress monitor to abort on | |
| 271 // a very large number of scans. 100 is arbitrary, but much larger | |
| 272 // than the number of scans we might expect in a normal image. | |
| 273 if (scan >= 100) { | |
| 274 error_exit(info); | |
| 275 } | |
| 276 } | |
| 277 | |
| 278 class JPEGImageReader final { | |
| 279 USING_FAST_MALLOC(JPEGImageReader); | |
| 280 WTF_MAKE_NONCOPYABLE(JPEGImageReader); | |
| 281 | |
| 282 public: | |
| 283 JPEGImageReader(JPEGImageDecoder* decoder) | |
| 284 : m_decoder(decoder), | |
| 285 m_needsRestart(false), | |
| 286 m_restartPosition(0), | |
| 287 m_nextReadPosition(0), | |
| 288 m_lastSetByte(nullptr), | |
| 289 m_state(JPEG_HEADER), | |
| 290 m_samples(nullptr) { | |
| 291 memset(&m_info, 0, sizeof(jpeg_decompress_struct)); | |
| 292 | |
| 293 // Set up the normal JPEG error routines, then override error_exit. | |
| 294 m_info.err = jpeg_std_error(&m_err.pub); | |
| 295 m_err.pub.error_exit = error_exit; | |
| 296 | |
| 297 // Allocate and initialize JPEG decompression object. | |
| 298 jpeg_create_decompress(&m_info); | |
| 299 | |
| 300 // Initialize source manager. | |
| 301 memset(&m_src, 0, sizeof(decoder_source_mgr)); | |
| 302 m_info.src = reinterpret_cast_ptr<jpeg_source_mgr*>(&m_src); | |
| 303 | |
| 304 // Set up callback functions. | |
| 305 m_src.pub.init_source = init_source; | |
| 306 m_src.pub.fill_input_buffer = fill_input_buffer; | |
| 307 m_src.pub.skip_input_data = skip_input_data; | |
| 308 m_src.pub.resync_to_restart = jpeg_resync_to_restart; | |
| 309 m_src.pub.term_source = term_source; | |
| 310 m_src.reader = this; | |
| 311 | |
| 312 // Set up a progress monitor. | |
| 313 m_info.progress = &m_progressMgr; | |
| 314 m_progressMgr.progress_monitor = progressMonitor; | |
| 315 | |
| 316 // Retain ICC color profile markers for color management. | |
| 317 setup_read_icc_profile(&m_info); | |
| 318 | |
| 319 // Keep APP1 blocks, for obtaining exif data. | |
| 320 jpeg_save_markers(&m_info, exifMarker, 0xFFFF); | |
| 321 } | |
| 322 | |
| 323 ~JPEGImageReader() { jpeg_destroy_decompress(&m_info); } | |
| 324 | |
| 325 void skipBytes(long numBytes) { | |
| 326 if (numBytes <= 0) | |
| 327 return; | |
| 328 | |
| 329 size_t bytesToSkip = static_cast<size_t>(numBytes); | |
| 330 | |
| 331 if (bytesToSkip < m_info.src->bytes_in_buffer) { | |
| 332 // The next byte needed is in the buffer. Move to it. | |
| 333 m_info.src->bytes_in_buffer -= bytesToSkip; | |
| 334 m_info.src->next_input_byte += bytesToSkip; | |
| 335 } else { | |
| 336 // Move beyond the buffer and empty it. | |
| 337 m_nextReadPosition = | |
| 338 m_nextReadPosition + bytesToSkip - m_info.src->bytes_in_buffer; | |
| 339 m_info.src->bytes_in_buffer = 0; | |
| 340 m_info.src->next_input_byte = nullptr; | |
| 341 } | |
| 342 | |
| 343 // This is a valid restart position. | |
| 344 m_restartPosition = m_nextReadPosition - m_info.src->bytes_in_buffer; | |
| 345 // We updated |next_input_byte|, so we need to update |m_lastByteSet| | |
| 346 // so we know not to update |m_restartPosition| again. | |
| 347 m_lastSetByte = m_info.src->next_input_byte; | |
| 348 } | |
| 349 | |
| 350 bool fillBuffer() { | |
| 351 if (m_needsRestart) { | |
| 352 m_needsRestart = false; | |
| 353 m_nextReadPosition = m_restartPosition; | |
| 354 } else { | |
| 355 updateRestartPosition(); | |
| 356 } | |
| 357 | |
| 358 const char* segment; | |
| 359 const size_t bytes = m_data->getSomeData(segment, m_nextReadPosition); | |
| 360 if (bytes == 0) { | |
| 361 // We had to suspend. When we resume, we will need to start from the | |
| 362 // restart position. | |
| 363 m_needsRestart = true; | |
| 364 clearBuffer(); | |
| 365 return false; | |
| 366 } | |
| 367 | |
| 368 m_nextReadPosition += bytes; | |
| 369 m_info.src->bytes_in_buffer = bytes; | |
| 370 const JOCTET* nextByte = reinterpret_cast_ptr<const JOCTET*>(segment); | |
| 371 m_info.src->next_input_byte = nextByte; | |
| 372 m_lastSetByte = nextByte; | |
| 373 return true; | |
| 374 } | |
| 375 | |
| 376 void setData(SegmentReader* data) { | |
| 377 if (m_data.get() == data) | |
| 378 return; | |
| 379 | |
| 380 m_data = data; | |
| 381 | |
| 382 // If a restart is needed, the next call to fillBuffer will read from the | |
| 383 // new SegmentReader. | |
| 384 if (m_needsRestart) | |
| 385 return; | |
| 386 | |
| 387 // Otherwise, empty the buffer, and leave the position the same, so | |
| 388 // fillBuffer continues reading from the same position in the new | |
| 389 // SegmentReader. | |
| 390 m_nextReadPosition -= m_info.src->bytes_in_buffer; | |
| 391 clearBuffer(); | |
| 392 } | |
| 393 | |
| 394 bool decode(bool onlySize) { | |
| 395 // We need to do the setjmp here. Otherwise bad things will happen | |
| 396 if (setjmp(m_err.setjmp_buffer)) | |
| 397 return m_decoder->setFailed(); | |
| 398 | |
| 399 J_COLOR_SPACE overrideColorSpace = JCS_UNKNOWN; | |
| 400 switch (m_state) { | |
| 401 case JPEG_HEADER: | |
| 402 // Read file parameters with jpeg_read_header(). | |
| 403 if (jpeg_read_header(&m_info, true) == JPEG_SUSPENDED) | |
| 404 return false; // I/O suspension. | |
| 405 | |
| 406 switch (m_info.jpeg_color_space) { | |
| 407 case JCS_YCbCr: | |
| 408 // libjpeg can convert YCbCr image pixels to RGB. | |
| 409 m_info.out_color_space = rgbOutputColorSpace(); | |
| 410 if (m_decoder->hasImagePlanes() && | |
| 411 (yuvSubsampling(m_info) != YUV_UNKNOWN)) | |
| 412 overrideColorSpace = JCS_YCbCr; | |
| 413 break; | |
| 414 case JCS_GRAYSCALE: | |
| 415 case JCS_RGB: | |
| 416 // libjpeg can convert GRAYSCALE image pixels to RGB. | |
| 417 m_info.out_color_space = rgbOutputColorSpace(); | |
| 418 break; | |
| 419 case JCS_CMYK: | |
| 420 case JCS_YCCK: | |
| 421 // libjpeg can convert YCCK to CMYK, but neither to RGB, so we | |
| 422 // manually convert CMKY to RGB. | |
| 423 m_info.out_color_space = JCS_CMYK; | |
| 424 break; | |
| 425 default: | |
| 426 return m_decoder->setFailed(); | |
| 427 } | |
| 428 | |
| 429 m_state = JPEG_START_DECOMPRESS; | |
| 430 | |
| 431 // We can fill in the size now that the header is available. | |
| 432 if (!m_decoder->setSize(m_info.image_width, m_info.image_height)) | |
| 433 return false; | |
| 434 | |
| 435 // Calculate and set decoded size. | |
| 436 m_info.scale_num = m_decoder->desiredScaleNumerator(); | |
| 437 m_info.scale_denom = scaleDenominator; | |
| 438 // Scaling caused by running low on memory isn't supported by YUV | |
| 439 // decoding since YUV decoding is performed on full sized images. At | |
| 440 // this point, buffers and various image info structs have already been | |
| 441 // set up for the scaled size after reading the image header using this | |
| 442 // decoder, so using the full size is no longer possible. | |
| 443 if (m_info.scale_num != m_info.scale_denom) | |
| 444 overrideColorSpace = JCS_UNKNOWN; | |
| 445 jpeg_calc_output_dimensions(&m_info); | |
| 446 m_decoder->setDecodedSize(m_info.output_width, m_info.output_height); | |
| 447 | |
| 448 m_decoder->setOrientation(readImageOrientation(info())); | |
| 449 | |
| 450 // Allow color management of the decoded RGBA pixels if possible. | |
| 451 if (!m_decoder->ignoresColorSpace()) { | |
| 452 JOCTET* profile = nullptr; | |
| 453 unsigned profileLength = 0; | |
| 454 if (read_icc_profile(info(), &profile, &profileLength)) { | |
| 455 decoder()->setEmbeddedColorProfile(reinterpret_cast<char*>(profile), | |
| 456 profileLength); | |
| 457 free(profile); | |
| 458 } | |
| 459 if (decoder()->colorTransform()) { | |
| 460 overrideColorSpace = JCS_UNKNOWN; | |
| 461 } | |
| 462 } | |
| 463 if (overrideColorSpace == JCS_YCbCr) { | |
| 464 m_info.out_color_space = JCS_YCbCr; | |
| 465 m_info.raw_data_out = TRUE; | |
| 466 m_uvSize = computeYUVSize( | |
| 467 &m_info, | |
| 468 1); // U size and V size have to be the same if we got here | |
| 469 } | |
| 470 | |
| 471 // Don't allocate a giant and superfluous memory buffer when the | |
| 472 // image is a sequential JPEG. | |
| 473 m_info.buffered_image = jpeg_has_multiple_scans(&m_info); | |
| 474 if (m_info.buffered_image) { | |
| 475 m_err.pub.emit_message = emit_message; | |
| 476 m_err.num_corrupt_warnings = 0; | |
| 477 } | |
| 478 | |
| 479 if (onlySize) { | |
| 480 // This exits the function while there is still potentially | |
| 481 // data in the buffer. Before this function is called again, | |
| 482 // the SharedBuffer may be collapsed (by a call to | |
| 483 // mergeSegmentsIntoBuffer), invalidating the "buffer" (which | |
| 484 // in reality is a pointer into the SharedBuffer's data). | |
| 485 // Defensively empty the buffer, but first find the latest | |
| 486 // restart position and signal to restart, so the next call to | |
| 487 // fillBuffer will resume from the correct point. | |
| 488 m_needsRestart = true; | |
| 489 updateRestartPosition(); | |
| 490 clearBuffer(); | |
| 491 return true; | |
| 492 } | |
| 493 // FALL THROUGH | |
| 494 | |
| 495 case JPEG_START_DECOMPRESS: | |
| 496 // Set parameters for decompression. | |
| 497 // FIXME -- Should reset dct_method and dither mode for final pass | |
| 498 // of progressive JPEG. | |
| 499 m_info.dct_method = JDCT_ISLOW; | |
| 500 m_info.dither_mode = JDITHER_FS; | |
| 501 m_info.do_fancy_upsampling = true; | |
| 502 m_info.do_block_smoothing = true; | |
| 503 m_info.enable_2pass_quant = false; | |
| 504 // FIXME: should we just assert these? | |
| 505 m_info.enable_external_quant = false; | |
| 506 m_info.enable_1pass_quant = false; | |
| 507 m_info.quantize_colors = false; | |
| 508 m_info.colormap = 0; | |
| 509 | |
| 510 // Make a one-row-high sample array that will go away when done with | |
| 511 // image. Always make it big enough to hold one RGBA row. Since this | |
| 512 // uses the IJG memory manager, it must be allocated before the call | |
| 513 // to jpeg_start_decompress(). | |
| 514 m_samples = allocateSampleArray(); | |
| 515 | |
| 516 // Start decompressor. | |
| 517 if (!jpeg_start_decompress(&m_info)) | |
| 518 return false; // I/O suspension. | |
| 519 | |
| 520 // If this is a progressive JPEG ... | |
| 521 m_state = (m_info.buffered_image) ? JPEG_DECOMPRESS_PROGRESSIVE | |
| 522 : JPEG_DECOMPRESS_SEQUENTIAL; | |
| 523 // FALL THROUGH | |
| 524 | |
| 525 case JPEG_DECOMPRESS_SEQUENTIAL: | |
| 526 if (m_state == JPEG_DECOMPRESS_SEQUENTIAL) { | |
| 527 if (!m_decoder->outputScanlines()) | |
| 528 return false; // I/O suspension. | |
| 529 | |
| 530 // If we've completed image output... | |
| 531 DCHECK_EQ(m_info.output_scanline, m_info.output_height); | |
| 532 m_state = JPEG_DONE; | |
| 533 } | |
| 534 // FALL THROUGH | |
| 535 | |
| 536 case JPEG_DECOMPRESS_PROGRESSIVE: | |
| 537 if (m_state == JPEG_DECOMPRESS_PROGRESSIVE) { | |
| 538 int status = 0; | |
| 539 do { | |
| 540 decoder_error_mgr* err = | |
| 541 reinterpret_cast_ptr<decoder_error_mgr*>(m_info.err); | |
| 542 if (err->num_corrupt_warnings) | |
| 543 break; | |
| 544 status = jpeg_consume_input(&m_info); | |
| 545 } while ((status != JPEG_SUSPENDED) && (status != JPEG_REACHED_EOI)); | |
| 546 | |
| 547 for (;;) { | |
| 548 if (!m_info.output_scanline) { | |
| 549 int scan = m_info.input_scan_number; | |
| 550 | |
| 551 // If we haven't displayed anything yet | |
| 552 // (output_scan_number == 0) and we have enough data for | |
| 553 // a complete scan, force output of the last full scan. | |
| 554 if (!m_info.output_scan_number && (scan > 1) && | |
| 555 (status != JPEG_REACHED_EOI)) | |
| 556 --scan; | |
| 557 | |
| 558 if (!jpeg_start_output(&m_info, scan)) | |
| 559 return false; // I/O suspension. | |
| 560 } | |
| 561 | |
| 562 if (m_info.output_scanline == 0xffffff) | |
| 563 m_info.output_scanline = 0; | |
| 564 | |
| 565 if (!m_decoder->outputScanlines()) { | |
| 566 if (m_decoder->failed()) | |
| 567 return false; | |
| 568 // If no scan lines were read, flag it so we don't call | |
| 569 // jpeg_start_output() multiple times for the same scan. | |
| 570 if (!m_info.output_scanline) | |
| 571 m_info.output_scanline = 0xffffff; | |
| 572 | |
| 573 return false; // I/O suspension. | |
| 574 } | |
| 575 | |
| 576 if (m_info.output_scanline == m_info.output_height) { | |
| 577 if (!jpeg_finish_output(&m_info)) | |
| 578 return false; // I/O suspension. | |
| 579 | |
| 580 if (jpeg_input_complete(&m_info) && | |
| 581 (m_info.input_scan_number == m_info.output_scan_number)) | |
| 582 break; | |
| 583 | |
| 584 m_info.output_scanline = 0; | |
| 585 } | |
| 586 } | |
| 587 | |
| 588 m_state = JPEG_DONE; | |
| 589 } | |
| 590 // FALL THROUGH | |
| 591 | |
| 592 case JPEG_DONE: | |
| 593 // Finish decompression. | |
| 594 return jpeg_finish_decompress(&m_info); | |
| 595 } | |
| 596 | |
| 597 return true; | |
| 598 } | |
| 599 | |
| 600 jpeg_decompress_struct* info() { return &m_info; } | |
| 601 JSAMPARRAY samples() const { return m_samples; } | |
| 602 JPEGImageDecoder* decoder() { return m_decoder; } | |
| 603 IntSize uvSize() const { return m_uvSize; } | |
| 604 | |
| 605 private: | |
| 606 JSAMPARRAY allocateSampleArray() { | |
| 607 // Some output color spaces don't need the sample array: don't allocate in that | |
| 608 // case. | |
| 609 #if defined(TURBO_JPEG_RGB_SWIZZLE) | |
| 610 if (turboSwizzled(m_info.out_color_space)) | |
| 611 return nullptr; | |
| 612 #endif | |
| 613 | |
| 614 if (m_info.out_color_space != JCS_YCbCr) | |
| 615 return (*m_info.mem->alloc_sarray)( | |
| 616 reinterpret_cast_ptr<j_common_ptr>(&m_info), JPOOL_IMAGE, | |
| 617 4 * m_info.output_width, 1); | |
| 618 | |
| 619 // Compute the width of the Y plane in bytes. This may be larger than the | |
| 620 // output width, since the jpeg library requires that the allocated width be | |
| 621 // a multiple of DCTSIZE. Note that this buffer will be used as garbage | |
| 622 // memory for rows that extend below the actual height of the image. We can | |
| 623 // reuse the same memory for the U and V planes, since we are guaranteed | |
| 624 // that the Y plane width is at least as large as the U and V plane widths. | |
| 625 int widthBytes = computeYUVWidthBytes(&m_info, 0); | |
| 626 return (*m_info.mem->alloc_sarray)( | |
| 627 reinterpret_cast_ptr<j_common_ptr>(&m_info), JPOOL_IMAGE, widthBytes, | |
| 628 1); | |
| 629 } | |
| 630 | |
| 631 void updateRestartPosition() { | |
| 632 if (m_lastSetByte != m_info.src->next_input_byte) { | |
| 633 // next_input_byte was updated by jpeg, meaning that it found a restart | |
| 634 // position. | |
| 635 m_restartPosition = m_nextReadPosition - m_info.src->bytes_in_buffer; | |
| 636 } | |
| 637 } | |
| 638 | |
| 639 void clearBuffer() { | |
| 640 // Let libjpeg know that the buffer needs to be refilled. | |
| 641 m_info.src->bytes_in_buffer = 0; | |
| 642 m_info.src->next_input_byte = nullptr; | |
| 643 m_lastSetByte = nullptr; | |
| 644 } | |
| 645 | |
| 646 RefPtr<SegmentReader> m_data; | |
| 647 JPEGImageDecoder* m_decoder; | |
| 648 | |
| 649 // Input reading: True if we need to back up to m_restartPosition. | |
| 650 bool m_needsRestart; | |
| 651 // If libjpeg needed to restart, this is the position to restart from. | |
| 652 size_t m_restartPosition; | |
| 653 // This is the position where we will read from, unless there is a restart. | |
| 654 size_t m_nextReadPosition; | |
| 655 // This is how we know to update the restart position. It is the last value | |
| 656 // we set to next_input_byte. libjpeg will update next_input_byte when it | |
| 657 // has found the next restart position, so if it no longer matches this | |
| 658 // value, we know we've reached the next restart position. | |
| 659 const JOCTET* m_lastSetByte; | |
| 660 | |
| 661 jpeg_decompress_struct m_info; | |
| 662 decoder_error_mgr m_err; | |
| 663 decoder_source_mgr m_src; | |
| 664 jpeg_progress_mgr m_progressMgr; | |
| 665 jstate m_state; | |
| 666 | |
| 667 JSAMPARRAY m_samples; | |
| 668 IntSize m_uvSize; | |
| 669 }; | |
| 670 | |
| 671 void error_exit( | |
| 672 j_common_ptr cinfo) // Decoding failed: return control to the setjmp point. | |
| 673 { | |
| 674 longjmp(reinterpret_cast_ptr<decoder_error_mgr*>(cinfo->err)->setjmp_buffer, | |
| 675 -1); | |
| 676 } | |
| 677 | |
| 678 void emit_message(j_common_ptr cinfo, int msg_level) { | |
| 679 if (msg_level >= 0) | |
| 680 return; | |
| 681 | |
| 682 decoder_error_mgr* err = reinterpret_cast_ptr<decoder_error_mgr*>(cinfo->err); | |
| 683 err->pub.num_warnings++; | |
| 684 | |
| 685 // Detect and count corrupt JPEG warning messages. | |
| 686 const char* warning = 0; | |
| 687 int code = err->pub.msg_code; | |
| 688 if (code > 0 && code <= err->pub.last_jpeg_message) | |
| 689 warning = err->pub.jpeg_message_table[code]; | |
| 690 if (warning && !strncmp("Corrupt JPEG", warning, 12)) | |
| 691 err->num_corrupt_warnings++; | |
| 692 } | |
| 693 | |
| 694 void init_source(j_decompress_ptr) {} | |
| 695 | |
| 696 void skip_input_data(j_decompress_ptr jd, long num_bytes) { | |
| 697 reinterpret_cast_ptr<decoder_source_mgr*>(jd->src)->reader->skipBytes( | |
| 698 num_bytes); | |
| 699 } | |
| 700 | |
| 701 boolean fill_input_buffer(j_decompress_ptr jd) { | |
| 702 return reinterpret_cast_ptr<decoder_source_mgr*>(jd->src) | |
| 703 ->reader->fillBuffer(); | |
| 704 } | |
| 705 | |
| 706 void term_source(j_decompress_ptr jd) { | |
| 707 reinterpret_cast_ptr<decoder_source_mgr*>(jd->src) | |
| 708 ->reader->decoder() | |
| 709 ->complete(); | |
| 710 } | |
| 711 | |
| 712 JPEGImageDecoder::JPEGImageDecoder(AlphaOption alphaOption, | 54 JPEGImageDecoder::JPEGImageDecoder(AlphaOption alphaOption, |
| 713 const ColorBehavior& colorBehavior, | 55 const ColorBehavior& colorBehavior, |
| 714 size_t maxDecodedBytes) | 56 size_t maxDecodedBytes) |
| 715 : ImageDecoder(alphaOption, colorBehavior, maxDecodedBytes) {} | 57 : ImageDecoder(alphaOption, colorOptions, maxDecodedBytes), |
| 58 m_codec(), |
| 59 m_setmentStream(nullptr) {} |
| 716 | 60 |
| 717 JPEGImageDecoder::~JPEGImageDecoder() {} | 61 JPEGImageDecoder::~JPEGImageDecoder() { |
| 62 if (!m_codec) { |
| 63 // if we did not create m_codec and thus did not pass ownership to it |
| 64 if (m_segmentStream) |
| 65 delete m_segmentStream; |
| 66 } |
| 67 } |
| 68 } |
| 718 | 69 |
| 719 bool JPEGImageDecoder::setSize(unsigned width, unsigned height) { | 70 bool JPEGImageDecoder::setSize(unsigned width, unsigned height) { |
| 720 if (!ImageDecoder::setSize(width, height)) | 71 if (!ImageDecoder::setSize(width, height)) |
| 721 return false; | 72 return false; |
| 722 | 73 |
| 723 if (!desiredScaleNumerator()) | 74 if (!desiredScaleNumerator()) |
| 724 return setFailed(); | 75 return setFailed(); |
| 725 | 76 |
| 726 setDecodedSize(width, height); | 77 setDecodedSize(width, height); |
| 727 return true; | 78 return true; |
| 728 } | 79 } |
| 729 | 80 |
| 730 void JPEGImageDecoder::onSetData(SegmentReader* data) { | 81 void JPEGImageDecoder::onSetData(SegmentReader* data) { |
| 731 if (m_reader) | 82 if (!data) { |
| 732 m_reader->setData(data); | 83 if (m_segmentStream) |
| 84 m_segmentStream->setReader(null, false); |
| 85 return; |
| 86 } |
| 87 |
| 88 if (!m_segmentStream) |
| 89 m_segmentStream = new SegmentStream(); |
| 90 |
| 91 m_segmentStream->setReader(data, isAllDataReceived()); |
| 92 |
| 93 // If we don't have a SkCodec yet, create one form the stream |
| 94 if (!m_codec) { |
| 95 SkCodec* codec = SkCodec::NewFromStream(m_segmentStream); |
| 96 if (codec) { |
| 97 m_codec.reset(codec); |
| 98 } else { |
| 99 // m_segmentStream's ownership is passed. It is deleted if SkCodec |
| 100 // creation fails. In this case, release our reference so we can create a |
| 101 // new SegmentStream later. |
| 102 m_segmentStream = nullptr; |
| 103 return; |
| 104 } |
| 105 |
| 106 // SkCodec::NewFromStream will read enough of the image to get the image |
| 107 // size. |
| 108 SkImageInfo imageInfo = m_codec->getInfo(); |
| 109 setSize(imageInfo.width(), imageInfo.height()); |
| 110 } |
| 733 } | 111 } |
| 734 | 112 |
| 735 void JPEGImageDecoder::setDecodedSize(unsigned width, unsigned height) { | 113 void JPEGImageDecoder::setDecodedSize(unsigned width, unsigned height) { |
| 736 m_decodedSize = IntSize(width, height); | 114 m_decodedSize = IntSize(width, height); |
| 737 } | 115 } |
| 738 | 116 |
| 739 IntSize JPEGImageDecoder::decodedYUVSize(int component) const { | 117 IntSize JPEGImageDecoder::decodedYUVSize(int component) const { |
| 740 DCHECK_GE(component, 0); | 118 DCHECK_GE(component, 0); |
| 741 DCHECK_LE(component, 2); | 119 DCHECK_LE(component, 2); |
| 742 DCHECK(m_reader); | 120 DCHECK(m_reader); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 785 decode(false); | 163 decode(false); |
| 786 PlatformInstrumentation::didDecodeImage(); | 164 PlatformInstrumentation::didDecodeImage(); |
| 787 return !failed(); | 165 return !failed(); |
| 788 } | 166 } |
| 789 | 167 |
| 790 void JPEGImageDecoder::setImagePlanes( | 168 void JPEGImageDecoder::setImagePlanes( |
| 791 std::unique_ptr<ImagePlanes> imagePlanes) { | 169 std::unique_ptr<ImagePlanes> imagePlanes) { |
| 792 m_imagePlanes = std::move(imagePlanes); | 170 m_imagePlanes = std::move(imagePlanes); |
| 793 } | 171 } |
| 794 | 172 |
| 795 template <J_COLOR_SPACE colorSpace> | |
| 796 void setPixel(ImageFrame& buffer, | |
| 797 ImageFrame::PixelData* pixel, | |
| 798 JSAMPARRAY samples, | |
| 799 int column) { | |
| 800 NOTREACHED(); | |
| 801 } | |
| 802 | |
| 803 // Used only for debugging with libjpeg (instead of libjpeg-turbo). | |
| 804 template <> | |
| 805 void setPixel<JCS_RGB>(ImageFrame& buffer, | |
| 806 ImageFrame::PixelData* pixel, | |
| 807 JSAMPARRAY samples, | |
| 808 int column) { | |
| 809 JSAMPLE* jsample = *samples + column * 3; | |
| 810 buffer.setRGBARaw(pixel, jsample[0], jsample[1], jsample[2], 255); | |
| 811 } | |
| 812 | |
| 813 template <> | |
| 814 void setPixel<JCS_CMYK>(ImageFrame& buffer, | |
| 815 ImageFrame::PixelData* pixel, | |
| 816 JSAMPARRAY samples, | |
| 817 int column) { | |
| 818 JSAMPLE* jsample = *samples + column * 4; | |
| 819 | |
| 820 // Source is 'Inverted CMYK', output is RGB. | |
| 821 // See: http://www.easyrgb.com/math.php?MATH=M12#text12 | |
| 822 // Or: http://www.ilkeratalay.com/colorspacesfaq.php#rgb | |
| 823 // From CMYK to CMY: | |
| 824 // X = X * (1 - K ) + K [for X = C, M, or Y] | |
| 825 // Thus, from Inverted CMYK to CMY is: | |
| 826 // X = (1-iX) * (1 - (1-iK)) + (1-iK) => 1 - iX*iK | |
| 827 // From CMY (0..1) to RGB (0..1): | |
| 828 // R = 1 - C => 1 - (1 - iC*iK) => iC*iK [G and B similar] | |
| 829 unsigned k = jsample[3]; | |
| 830 buffer.setRGBARaw(pixel, jsample[0] * k / 255, jsample[1] * k / 255, | |
| 831 jsample[2] * k / 255, 255); | |
| 832 } | |
| 833 | |
| 834 // Used only for JCS_CMYK and JCS_RGB output. Note that JCS_RGB is used only | |
| 835 // for debugging with libjpeg (instead of libjpeg-turbo). | |
| 836 template <J_COLOR_SPACE colorSpace> | |
| 837 bool outputRows(JPEGImageReader* reader, ImageFrame& buffer) { | |
| 838 JSAMPARRAY samples = reader->samples(); | |
| 839 jpeg_decompress_struct* info = reader->info(); | |
| 840 int width = info->output_width; | |
| 841 | |
| 842 while (info->output_scanline < info->output_height) { | |
| 843 // jpeg_read_scanlines will increase the scanline counter, so we | |
| 844 // save the scanline before calling it. | |
| 845 int y = info->output_scanline; | |
| 846 // Request one scanline: returns 0 or 1 scanlines. | |
| 847 if (jpeg_read_scanlines(info, samples, 1) != 1) | |
| 848 return false; | |
| 849 | |
| 850 ImageFrame::PixelData* pixel = buffer.getAddr(0, y); | |
| 851 for (int x = 0; x < width; ++pixel, ++x) | |
| 852 setPixel<colorSpace>(buffer, pixel, samples, x); | |
| 853 | |
| 854 SkColorSpaceXform* xform = reader->decoder()->colorTransform(); | |
| 855 if (JCS_RGB == colorSpace && xform) { | |
| 856 ImageFrame::PixelData* row = buffer.getAddr(0, y); | |
| 857 xform->apply(xformColorFormat(), row, xformColorFormat(), row, width, | |
| 858 kOpaque_SkAlphaType); | |
| 859 } | |
| 860 } | |
| 861 | |
| 862 buffer.setPixelsChanged(true); | |
| 863 return true; | |
| 864 } | |
| 865 | |
| 866 static bool outputRawData(JPEGImageReader* reader, ImagePlanes* imagePlanes) { | |
| 867 JSAMPARRAY samples = reader->samples(); | |
| 868 jpeg_decompress_struct* info = reader->info(); | |
| 869 | |
| 870 JSAMPARRAY bufferraw[3]; | |
| 871 JSAMPROW bufferraw2[32]; | |
| 872 bufferraw[0] = &bufferraw2[0]; // Y channel rows (8 or 16) | |
| 873 bufferraw[1] = &bufferraw2[16]; // U channel rows (8) | |
| 874 bufferraw[2] = &bufferraw2[24]; // V channel rows (8) | |
| 875 int yHeight = info->output_height; | |
| 876 int v = info->comp_info[0].v_samp_factor; | |
| 877 IntSize uvSize = reader->uvSize(); | |
| 878 int uvHeight = uvSize.height(); | |
| 879 JSAMPROW outputY = static_cast<JSAMPROW>(imagePlanes->plane(0)); | |
| 880 JSAMPROW outputU = static_cast<JSAMPROW>(imagePlanes->plane(1)); | |
| 881 JSAMPROW outputV = static_cast<JSAMPROW>(imagePlanes->plane(2)); | |
| 882 size_t rowBytesY = imagePlanes->rowBytes(0); | |
| 883 size_t rowBytesU = imagePlanes->rowBytes(1); | |
| 884 size_t rowBytesV = imagePlanes->rowBytes(2); | |
| 885 | |
| 886 // Request 8 or 16 scanlines: returns 0 or more scanlines. | |
| 887 int yScanlinesToRead = DCTSIZE * v; | |
| 888 JSAMPROW dummyRow = *samples; | |
| 889 while (info->output_scanline < info->output_height) { | |
| 890 // Assign 8 or 16 rows of memory to read the Y channel. | |
| 891 for (int i = 0; i < yScanlinesToRead; ++i) { | |
| 892 int scanline = info->output_scanline + i; | |
| 893 if (scanline < yHeight) { | |
| 894 bufferraw2[i] = &outputY[scanline * rowBytesY]; | |
| 895 } else { | |
| 896 bufferraw2[i] = dummyRow; | |
| 897 } | |
| 898 } | |
| 899 | |
| 900 // Assign 8 rows of memory to read the U and V channels. | |
| 901 int scaledScanline = info->output_scanline / v; | |
| 902 for (int i = 0; i < 8; ++i) { | |
| 903 int scanline = scaledScanline + i; | |
| 904 if (scanline < uvHeight) { | |
| 905 bufferraw2[16 + i] = &outputU[scanline * rowBytesU]; | |
| 906 bufferraw2[24 + i] = &outputV[scanline * rowBytesV]; | |
| 907 } else { | |
| 908 bufferraw2[16 + i] = dummyRow; | |
| 909 bufferraw2[24 + i] = dummyRow; | |
| 910 } | |
| 911 } | |
| 912 | |
| 913 JDIMENSION scanlinesRead = | |
| 914 jpeg_read_raw_data(info, bufferraw, yScanlinesToRead); | |
| 915 if (!scanlinesRead) | |
| 916 return false; | |
| 917 } | |
| 918 | |
| 919 info->output_scanline = std::min(info->output_scanline, info->output_height); | |
| 920 return true; | |
| 921 } | |
| 922 | |
| 923 bool JPEGImageDecoder::outputScanlines() { | 173 bool JPEGImageDecoder::outputScanlines() { |
| 924 if (hasImagePlanes()) | 174 if (hasImagePlanes()) |
| 925 return outputRawData(m_reader.get(), m_imagePlanes.get()); | 175 return outputRawData(m_reader.get(), m_imagePlanes.get()); |
| 926 | 176 |
| 927 if (m_frameBufferCache.isEmpty()) | 177 if (m_frameBufferCache.isEmpty()) |
| 928 return false; | 178 return false; |
| 929 | 179 |
| 930 jpeg_decompress_struct* info = m_reader->info(); | 180 jpeg_decompress_struct* info = m_reader->info(); |
| 931 | 181 |
| 932 // Initialize the framebuffer if needed. | 182 // Initialize the framebuffer if needed. |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 975 return outputRows<JCS_RGB>(m_reader.get(), buffer); | 225 return outputRows<JCS_RGB>(m_reader.get(), buffer); |
| 976 case JCS_CMYK: | 226 case JCS_CMYK: |
| 977 return outputRows<JCS_CMYK>(m_reader.get(), buffer); | 227 return outputRows<JCS_CMYK>(m_reader.get(), buffer); |
| 978 default: | 228 default: |
| 979 NOTREACHED(); | 229 NOTREACHED(); |
| 980 } | 230 } |
| 981 | 231 |
| 982 return setFailed(); | 232 return setFailed(); |
| 983 } | 233 } |
| 984 | 234 |
| 235 bool JPEGImageDecoder::frameIsCompleteAtIndex(size_t index) const { |
| 236 if (!m_codec) |
| 237 return false; |
| 238 |
| 239 if (index >= 1) |
| 240 return false; |
| 241 |
| 242 if (m_frameBufferCache.isEmpty()) |
| 243 return false; |
| 244 |
| 245 return m_frameBufferCache[0].getStatus() == ImageFrame::FrameComplete; |
| 246 } |
| 247 |
| 248 |
| 249 |
| 250 |
| 251 |
| 985 void JPEGImageDecoder::complete() { | 252 void JPEGImageDecoder::complete() { |
| 986 if (m_frameBufferCache.isEmpty()) | 253 if (m_frameBufferCache.isEmpty()) |
| 987 return; | 254 return; |
| 988 | 255 |
| 989 m_frameBufferCache[0].setHasAlpha(false); | 256 m_frameBufferCache[0].setHasAlpha(false); |
| 990 m_frameBufferCache[0].setStatus(ImageFrame::FrameComplete); | 257 m_frameBufferCache[0].setStatus(ImageFrame::FrameComplete); |
| 991 } | 258 } |
| 992 | 259 |
| 993 inline bool isComplete(const JPEGImageDecoder* decoder, bool onlySize) { | 260 inline bool isComplete(const JPEGImageDecoder* decoder, bool onlySize) { |
| 994 if (decoder->hasImagePlanes() && !onlySize) | 261 if (decoder->hasImagePlanes() && !onlySize) |
| 995 return true; | 262 return true; |
| 996 | 263 |
| 997 return decoder->frameIsCompleteAtIndex(0); | 264 return decoder->frameIsCompleteAtIndex(0); |
| 998 } | 265 } |
| 999 | 266 |
| 1000 void JPEGImageDecoder::decode(bool onlySize) { | 267 void JPEGImageDecoder::decode(bool onlySize) { |
| 1001 if (failed()) | 268 if (failed()) |
| 1002 return; | 269 return; |
| 1003 | 270 |
| 1004 if (!m_reader) { | 271 if (!m_codec) |
| 1005 m_reader = WTF::makeUnique<JPEGImageReader>(this); | 272 return; |
| 1006 m_reader->setData(m_data.get()); | 273 |
| 274 if (m_frameBufferCache.size() <= index) { |
| 275 // It is a fatal error if all data is received and the file is truncated. |
| 276 if (isAllDataReceived()) |
| 277 setFailed(); |
| 278 |
| 279 return; |
| 1007 } | 280 } |
| 1008 | 281 |
| 1009 // If we couldn't decode the image but have received all the data, decoding | 282 SkImageInfo imageInfo = m_codec->getInfo().makeColorType(kN32_SkColorType); |
| 1010 // has failed. | |
| 1011 if (!m_reader->decode(onlySize) && isAllDataReceived()) | |
| 1012 setFailed(); | |
| 1013 | 283 |
| 1014 // If decoding is done or failed, we don't need the JPEGImageReader anymore. | 284 SkCodec::Options options; |
| 1015 if (isComplete(this, onlySize) || failed()) | 285 options.fZeroInitialized = true; |
| 1016 m_reader.reset(); | 286 |
| 287 ImageFrame& frame = m_frameBufferCache[index]; |
| 288 if (frame.getStatus() == ImageFrame::FrameEmpty) { |
| 289 frame.allocatePixelData(size().width(), size().height(), |
| 290 colorSpaceForSkImages()); |
| 291 frame.zeroFillPixelData(); |
| 292 } else { |
| 293 SkCodec::Result startIncrementalDecodeResult = |
| 294 m_codec->startIncrementalDecode(imageInfo, frame.bitmap().getPixels(), |
| 295 frame.bitmap().rowBytes(), &options, |
| 296 nullptr, nullptr); |
| 297 switch (startIncrementalDecodeResult) { |
| 298 case SkCodec::kSuccess: |
| 299 break; |
| 300 case SkCodec::kIncompleteInput: |
| 301 return; |
| 302 default: |
| 303 setFailed(); |
| 304 return; |
| 305 } |
| 306 frame.setStatus(ImageFrame::framePartial); |
| 307 } |
| 308 |
| 309 int rowsDecoded = 0; |
| 310 SkCodec::Result incrementalDecodeResult = |
| 311 m_codec->incrementalDecode(&rowsDecoded); |
| 312 switch (incrementalDecodeResult) { |
| 313 case SkCodec::kSuccess: |
| 314 frame.setPixelsChanged(true); |
| 315 frame.setStatus(ImageFrame::FrameComplete); |
| 316 postDecodeProcessing(index); |
| 317 break; |
| 318 case SkCodec::kIncompleteInput: |
| 319 if (frameIsCompleteAtIndex(index) || isAllDataReceived()) { |
| 320 setFailed(); |
| 321 return; |
| 322 } |
| 323 |
| 324 { |
| 325 IntRect remainingRect = frame.originalFrameRect(); |
| 326 remainingRect.setY(rowsDecoded); |
| 327 remainingRect.setHeight(remainingRect.height() - rowsDecoded); |
| 328 } |
| 329 |
| 330 frame.setPixelsChanged(true); |
| 331 break; |
| 332 default: |
| 333 setFailed(); |
| 334 return; |
| 335 } |
| 1017 } | 336 } |
| 1018 | 337 |
| 1019 } // namespace blink | 338 } // namespace blink |
| OLD | NEW |