nsJPEGDecoder.cpp (37660B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * 3 * This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "ImageLogging.h" // Must appear first. 8 9 #include "nsJPEGDecoder.h" 10 11 #include <cstdint> 12 13 #include "imgFrame.h" 14 #include "Orientation.h" 15 #include "EXIF.h" 16 #include "SurfacePipeFactory.h" 17 18 #include "nspr.h" 19 #include "nsCRT.h" 20 #include "gfxColor.h" 21 22 #include "jerror.h" 23 24 #include "gfxPlatform.h" 25 #include "mozilla/EndianUtils.h" 26 #include "mozilla/gfx/Types.h" 27 28 extern "C" { 29 #include "iccjpeg.h" 30 } 31 32 #if MOZ_BIG_ENDIAN() 33 # define MOZ_JCS_EXT_NATIVE_ENDIAN_XRGB JCS_EXT_XRGB 34 #else 35 # define MOZ_JCS_EXT_NATIVE_ENDIAN_XRGB JCS_EXT_BGRX 36 #endif 37 38 static void cmyk_convert_bgra(uint32_t* aInput, uint32_t* aOutput, 39 int32_t aWidth, bool aIsInverted); 40 41 using mozilla::gfx::SurfaceFormat; 42 43 namespace mozilla { 44 namespace image { 45 46 static mozilla::LazyLogModule sJPEGLog("JPEGDecoder"); 47 48 static mozilla::LazyLogModule sJPEGDecoderAccountingLog( 49 "JPEGDecoderAccounting"); 50 51 static qcms_profile* GetICCProfile(struct jpeg_decompress_struct& info) { 52 JOCTET* profilebuf; 53 uint32_t profileLength; 54 qcms_profile* profile = nullptr; 55 56 if (read_icc_profile(&info, &profilebuf, &profileLength)) { 57 profile = qcms_profile_from_memory(profilebuf, profileLength); 58 free(profilebuf); 59 } 60 61 return profile; 62 } 63 64 METHODDEF(void) init_source(j_decompress_ptr jd); 65 METHODDEF(boolean) fill_input_buffer(j_decompress_ptr jd); 66 METHODDEF(void) skip_input_data(j_decompress_ptr jd, long num_bytes); 67 METHODDEF(void) term_source(j_decompress_ptr jd); 68 METHODDEF(void) my_error_exit(j_common_ptr cinfo); 69 METHODDEF(void) progress_monitor(j_common_ptr info); 70 71 // Normal JFIF markers can't have more bytes than this. 72 #define MAX_JPEG_MARKER_LENGTH (((uint32_t)1 << 16) - 1) 73 74 nsJPEGDecoder::nsJPEGDecoder(RasterImage* aImage, 75 Decoder::DecodeStyle aDecodeStyle, bool aIsPDF) 76 : Decoder(aImage), 77 mLexer(Transition::ToUnbuffered(State::FINISHED_JPEG_DATA, 78 State::JPEG_DATA, SIZE_MAX), 79 Transition::TerminateSuccess()), 80 mProfile(nullptr), 81 mProfileLength(0), 82 mCMSLine(nullptr), 83 mDecodeStyle(aDecodeStyle), 84 mIsPDF(aIsPDF) { 85 this->mErr.pub.error_exit = nullptr; 86 this->mErr.pub.emit_message = nullptr; 87 this->mErr.pub.output_message = nullptr; 88 this->mErr.pub.format_message = nullptr; 89 this->mErr.pub.reset_error_mgr = nullptr; 90 this->mErr.pub.msg_code = 0; 91 this->mErr.pub.trace_level = 0; 92 this->mErr.pub.num_warnings = 0; 93 this->mErr.pub.jpeg_message_table = nullptr; 94 this->mErr.pub.last_jpeg_message = 0; 95 this->mErr.pub.addon_message_table = nullptr; 96 this->mErr.pub.first_addon_message = 0; 97 this->mErr.pub.last_addon_message = 0; 98 mState = JPEG_HEADER; 99 mReading = true; 100 mImageData = nullptr; 101 102 mBytesToSkip = 0; 103 memset(&mInfo, 0, sizeof(jpeg_decompress_struct)); 104 memset(&mSourceMgr, 0, sizeof(mSourceMgr)); 105 memset(&mProgressMgr, 0, sizeof(mProgressMgr)); 106 mInfo.client_data = (void*)this; 107 108 mSegment = nullptr; 109 mSegmentLen = 0; 110 111 mBackBuffer = nullptr; 112 mBackBufferLen = mBackBufferSize = mBackBufferUnreadLen = 0; 113 114 MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug, 115 ("nsJPEGDecoder::nsJPEGDecoder: Creating JPEG decoder %p", this)); 116 } 117 118 nsJPEGDecoder::~nsJPEGDecoder() { 119 // Step 8: Release JPEG decompression object 120 mInfo.src = nullptr; 121 jpeg_destroy_decompress(&mInfo); 122 123 free(mBackBuffer); 124 mBackBuffer = nullptr; 125 126 delete[] mCMSLine; 127 128 MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug, 129 ("nsJPEGDecoder::~nsJPEGDecoder: Destroying JPEG decoder %p", this)); 130 } 131 132 Maybe<glean::impl::MemoryDistributionMetric> nsJPEGDecoder::SpeedMetric() 133 const { 134 return Some(glean::image_decode::speed_jpeg); 135 } 136 137 nsresult nsJPEGDecoder::InitInternal() { 138 // We set up the normal JPEG error routines, then override error_exit. 139 mInfo.err = jpeg_std_error(&mErr.pub); 140 // mInfo.err = jpeg_std_error(&mErr.pub); 141 mErr.pub.error_exit = my_error_exit; 142 // Establish the setjmp return context for my_error_exit to use. 143 if (setjmp(mErr.setjmp_buffer)) { 144 // If we get here, the JPEG code has signaled an error, and initialization 145 // has failed. 146 return NS_ERROR_FAILURE; 147 } 148 149 // Step 1: allocate and initialize JPEG decompression object 150 jpeg_create_decompress(&mInfo); 151 // Set the source manager 152 mInfo.src = &mSourceMgr; 153 154 // Step 2: specify data source (eg, a file) 155 156 // Setup callback functions. 157 mSourceMgr.init_source = init_source; 158 mSourceMgr.fill_input_buffer = fill_input_buffer; 159 mSourceMgr.skip_input_data = skip_input_data; 160 mSourceMgr.resync_to_restart = jpeg_resync_to_restart; 161 mSourceMgr.term_source = term_source; 162 163 mInfo.mem->max_memory_to_use = static_cast<long>( 164 std::min<size_t>(SurfaceCache::MaximumCapacity(), LONG_MAX)); 165 166 mProgressMgr.progress_monitor = &progress_monitor; 167 mInfo.progress = &mProgressMgr; 168 169 // Record app markers for ICC data 170 for (uint32_t m = 0; m < 16; m++) { 171 jpeg_save_markers(&mInfo, JPEG_APP0 + m, 0xFFFF); 172 } 173 174 return NS_OK; 175 } 176 177 nsresult nsJPEGDecoder::FinishInternal() { 178 // If we're not in any sort of error case, force our state to JPEG_DONE. 179 if ((mState != JPEG_DONE && mState != JPEG_SINK_NON_JPEG_TRAILER) && 180 (mState != JPEG_ERROR) && !IsMetadataDecode()) { 181 mState = JPEG_DONE; 182 } 183 184 return NS_OK; 185 } 186 187 LexerResult nsJPEGDecoder::DoDecode(SourceBufferIterator& aIterator, 188 IResumable* aOnResume) { 189 MOZ_ASSERT(!HasError(), "Shouldn't call DoDecode after error!"); 190 191 return mLexer.Lex(aIterator, aOnResume, 192 [=](State aState, const char* aData, size_t aLength) { 193 switch (aState) { 194 case State::JPEG_DATA: 195 return ReadJPEGData(aData, aLength); 196 case State::FINISHED_JPEG_DATA: 197 return FinishedJPEGData(); 198 } 199 MOZ_CRASH("Unknown State"); 200 }); 201 } 202 203 LexerTransition<nsJPEGDecoder::State> nsJPEGDecoder::ReadJPEGData( 204 const char* aData, size_t aLength) { 205 mSegment = reinterpret_cast<const JOCTET*>(aData); 206 mSegmentLen = aLength; 207 208 // Return here if there is a error within libjpeg. 209 nsresult error_code; 210 // This cast to nsresult makes sense because setjmp() returns whatever we 211 // passed to longjmp(), which was actually an nsresult. These error codes 212 // have been translated from libjpeg error codes, like so: 213 // JERR_OUT_OF_MEMORY => NS_ERROR_OUT_OF_MEMORY 214 // JERR_UNKNOWN_MARKER => NS_ERROR_ILLEGAL_VALUE 215 // JERR_SOF_UNSUPPORTED => NS_ERROR_INVALID_CONTENT_ENCODING 216 // <any other error> => NS_ERROR_FAILURE 217 if ((error_code = static_cast<nsresult>(setjmp(mErr.setjmp_buffer))) != 218 NS_OK) { 219 bool fatal = true; 220 if (error_code == NS_ERROR_FAILURE) { 221 // Error due to corrupt data. Make sure that we don't feed any more data 222 // to libjpeg-turbo. 223 mState = JPEG_SINK_NON_JPEG_TRAILER; 224 MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug, 225 ("} (setjmp returned NS_ERROR_FAILURE)")); 226 } else if (error_code == NS_ERROR_ILLEGAL_VALUE) { 227 // This is a recoverable error. Consume the marker and continue. 228 mInfo.unread_marker = 0; 229 fatal = false; 230 } else if (error_code == NS_ERROR_INVALID_CONTENT_ENCODING) { 231 // The content is encoding frames with a format that libjpeg can't handle. 232 MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug, 233 ("} (setjmp returned NS_ERROR_INVALID_CONTENT_ENCODING)")); 234 // Check to see if we're in the done state, which indicates that we've 235 // already processed the main JPEG data. 236 bool inDoneState = (mState == JPEG_DONE); 237 // Whether we succeed or fail, we shouldn't send any more data. 238 mState = JPEG_SINK_NON_JPEG_TRAILER; 239 240 // If we're in the done state, we exit successfully and attempt to 241 // display the content we've already received. Otherwise, we fallthrough 242 // and treat this as a fatal error. 243 if (inDoneState) { 244 return Transition::TerminateSuccess(); 245 } 246 } else { 247 // Error for another reason. (Possibly OOM.) 248 mState = JPEG_ERROR; 249 MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug, 250 ("} (setjmp returned an error)")); 251 } 252 253 if (fatal) { 254 return Transition::TerminateFailure(); 255 } 256 } 257 258 MOZ_LOG(sJPEGLog, LogLevel::Debug, 259 ("[this=%p] nsJPEGDecoder::Write -- processing JPEG data\n", this)); 260 261 switch (mState) { 262 case JPEG_HEADER: { 263 LOG_SCOPE((mozilla::LogModule*)sJPEGLog, 264 "nsJPEGDecoder::Write -- entering JPEG_HEADER" 265 " case"); 266 267 // Step 3: read file parameters with jpeg_read_header() 268 if (jpeg_read_header(&mInfo, TRUE) == JPEG_SUSPENDED) { 269 MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug, 270 ("} (JPEG_SUSPENDED)")); 271 return Transition::ContinueUnbuffered( 272 State::JPEG_DATA); // I/O suspension 273 } 274 275 // Post our size to the superclass 276 EXIFData exif = ReadExifData(); 277 PostSize(mInfo.image_width, mInfo.image_height, exif.orientation, 278 exif.resolution); 279 if (WantsFrameCount()) { 280 PostFrameCount(/* aFrameCount */ 1); 281 } 282 if (HasError()) { 283 // Setting the size led to an error. 284 mState = JPEG_ERROR; 285 return Transition::TerminateFailure(); 286 } 287 288 // If we're doing a metadata decode, we're done. 289 if (IsMetadataDecode()) { 290 return Transition::TerminateSuccess(); 291 } 292 293 // We're doing a full decode. 294 switch (mInfo.jpeg_color_space) { 295 case JCS_GRAYSCALE: 296 case JCS_RGB: 297 case JCS_YCbCr: 298 // By default, we will output directly to BGRA. If we need to apply 299 // special color transforms, this may change. 300 switch (SurfaceFormat::OS_RGBX) { 301 case SurfaceFormat::B8G8R8X8: 302 mInfo.out_color_space = JCS_EXT_BGRX; 303 break; 304 case SurfaceFormat::X8R8G8B8: 305 mInfo.out_color_space = JCS_EXT_XRGB; 306 break; 307 case SurfaceFormat::R8G8B8X8: 308 mInfo.out_color_space = JCS_EXT_RGBX; 309 break; 310 default: 311 mState = JPEG_ERROR; 312 return Transition::TerminateFailure(); 313 } 314 break; 315 case JCS_CMYK: 316 case JCS_YCCK: 317 // libjpeg can convert from YCCK to CMYK, but not to XRGB. 318 mInfo.out_color_space = JCS_CMYK; 319 break; 320 default: 321 mState = JPEG_ERROR; 322 MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug, 323 ("} (unknown colorspace (3))")); 324 return Transition::TerminateFailure(); 325 } 326 327 if (mCMSMode != CMSMode::Off) { 328 if ((mInProfile = GetICCProfile(mInfo)) != nullptr && 329 GetCMSOutputProfile()) { 330 uint32_t profileSpace = qcms_profile_get_color_space(mInProfile); 331 332 qcms_data_type outputType = gfxPlatform::GetCMSOSRGBAType(); 333 Maybe<qcms_data_type> inputType; 334 if (profileSpace == icSigRgbData) { 335 // We can always color manage RGB profiles since it happens at the 336 // end of the pipeline. 337 inputType.emplace(outputType); 338 } else if (profileSpace == icSigGrayData && 339 mInfo.jpeg_color_space == JCS_GRAYSCALE) { 340 // We can only color manage gray profiles if the original color 341 // space is grayscale. This means we must downscale after color 342 // management since the downscaler assumes BGRA. 343 mInfo.out_color_space = JCS_GRAYSCALE; 344 inputType.emplace(QCMS_DATA_GRAY_8); 345 } 346 347 #if 0 348 // We don't currently support CMYK profiles. The following 349 // code dealt with lcms types. Add something like this 350 // back when we gain support for CMYK. 351 352 // Adobe Photoshop writes YCCK/CMYK files with inverted data 353 if (mInfo.out_color_space == JCS_CMYK) { 354 type |= FLAVOR_SH(mInfo.saw_Adobe_marker ? 1 : 0); 355 } 356 #endif 357 358 if (inputType) { 359 // Calculate rendering intent. 360 int intent = gfxPlatform::GetRenderingIntent(); 361 if (intent == -1) { 362 intent = qcms_profile_get_rendering_intent(mInProfile); 363 } 364 365 // Create the color management transform. 366 mTransform = qcms_transform_create(mInProfile, *inputType, 367 GetCMSOutputProfile(), 368 outputType, (qcms_intent)intent); 369 } 370 } else if (mCMSMode == CMSMode::All) { 371 mTransform = GetCMSsRGBTransform(SurfaceFormat::OS_RGBX); 372 } 373 } 374 375 // We don't want to use the pipe buffers directly because we don't want 376 // any reads on non-BGRA formatted data. 377 if (mInfo.out_color_space == JCS_GRAYSCALE || 378 mInfo.out_color_space == JCS_CMYK) { 379 mCMSLine = new (std::nothrow) uint32_t[mInfo.image_width]; 380 if (!mCMSLine) { 381 mState = JPEG_ERROR; 382 MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug, 383 ("} (could allocate buffer for color conversion)")); 384 return Transition::TerminateFailure(); 385 } 386 } 387 388 // Don't allocate a giant and superfluous memory buffer 389 // when not doing a progressive decode. 390 mInfo.buffered_image = 391 mDecodeStyle == PROGRESSIVE && jpeg_has_multiple_scans(&mInfo); 392 393 /* Used to set up image size so arrays can be allocated */ 394 jpeg_calc_output_dimensions(&mInfo); 395 396 // We handle the transform outside the pipeline if we are outputting in 397 // grayscale, because the pipeline wants BGRA pixels, particularly the 398 // downscaling filter, so we can't handle it after downscaling as would 399 // be optimal. 400 qcms_transform* pipeTransform = 401 mInfo.out_color_space != JCS_GRAYSCALE ? mTransform : nullptr; 402 403 Maybe<SurfacePipe> pipe = SurfacePipeFactory::CreateReorientSurfacePipe( 404 this, Size(), OutputSize(), SurfaceFormat::OS_RGBX, 405 SurfaceFormat::OS_RGBX, pipeTransform, GetOrientation(), 406 SurfacePipeFlags()); 407 if (!pipe) { 408 mState = JPEG_ERROR; 409 MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug, 410 ("} (could not initialize surface pipe)")); 411 return Transition::TerminateFailure(); 412 } 413 414 mPipe = std::move(*pipe); 415 416 MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug, 417 (" JPEGDecoderAccounting: nsJPEGDecoder::" 418 "Write -- created image frame with %ux%u pixels", 419 mInfo.image_width, mInfo.image_height)); 420 421 mState = JPEG_START_DECOMPRESS; 422 [[fallthrough]]; // to start decompressing. 423 } 424 425 case JPEG_START_DECOMPRESS: { 426 LOG_SCOPE((mozilla::LogModule*)sJPEGLog, 427 "nsJPEGDecoder::Write -- entering" 428 " JPEG_START_DECOMPRESS case"); 429 // Step 4: set parameters for decompression 430 431 // FIXME -- Should reset dct_method and dither mode 432 // for final pass of progressive JPEG 433 434 mInfo.dct_method = JDCT_ISLOW; 435 mInfo.dither_mode = JDITHER_FS; 436 mInfo.do_fancy_upsampling = TRUE; 437 mInfo.enable_2pass_quant = FALSE; 438 mInfo.do_block_smoothing = TRUE; 439 440 // Step 5: Start decompressor 441 if (jpeg_start_decompress(&mInfo) == FALSE) { 442 MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug, 443 ("} (I/O suspension after jpeg_start_decompress())")); 444 return Transition::ContinueUnbuffered( 445 State::JPEG_DATA); // I/O suspension 446 } 447 448 // If this is a progressive JPEG ... 449 mState = mInfo.buffered_image ? JPEG_DECOMPRESS_PROGRESSIVE 450 : JPEG_DECOMPRESS_SEQUENTIAL; 451 [[fallthrough]]; // to decompress sequential JPEG. 452 } 453 454 case JPEG_DECOMPRESS_SEQUENTIAL: { 455 if (mState == JPEG_DECOMPRESS_SEQUENTIAL) { 456 LOG_SCOPE((mozilla::LogModule*)sJPEGLog, 457 "nsJPEGDecoder::Write -- " 458 "JPEG_DECOMPRESS_SEQUENTIAL case"); 459 460 switch (OutputScanlines()) { 461 case WriteState::NEED_MORE_DATA: 462 MOZ_LOG( 463 sJPEGDecoderAccountingLog, LogLevel::Debug, 464 ("} (I/O suspension after OutputScanlines() - SEQUENTIAL)")); 465 return Transition::ContinueUnbuffered( 466 State::JPEG_DATA); // I/O suspension 467 case WriteState::FINISHED: 468 NS_ASSERTION(mInfo.output_scanline == mInfo.output_height, 469 "We didn't process all of the data!"); 470 mState = JPEG_DONE; 471 break; 472 case WriteState::FAILURE: 473 mState = JPEG_ERROR; 474 MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug, 475 ("} (Error in pipeline from OutputScalines())")); 476 return Transition::TerminateFailure(); 477 } 478 } 479 [[fallthrough]]; // to decompress progressive JPEG. 480 } 481 482 case JPEG_DECOMPRESS_PROGRESSIVE: { 483 if (mState == JPEG_DECOMPRESS_PROGRESSIVE) { 484 LOG_SCOPE((mozilla::LogModule*)sJPEGLog, 485 "nsJPEGDecoder::Write -- JPEG_DECOMPRESS_PROGRESSIVE case"); 486 auto AllComponentsSeen = [](jpeg_decompress_struct& info) { 487 bool all_components_seen = true; 488 if (info.coef_bits) { 489 for (int c = 0; c < info.num_components; ++c) { 490 bool current_component_seen = info.coef_bits[c][0] != -1; 491 all_components_seen &= current_component_seen; 492 } 493 } 494 return all_components_seen; 495 }; 496 int status; 497 int scan_to_display_first = 0; 498 bool all_components_seen; 499 all_components_seen = AllComponentsSeen(mInfo); 500 if (all_components_seen) { 501 scan_to_display_first = mInfo.input_scan_number; 502 } 503 504 do { 505 status = jpeg_consume_input(&mInfo); 506 507 if (status == JPEG_REACHED_SOS || status == JPEG_REACHED_EOI || 508 status == JPEG_SUSPENDED) { 509 // record the first scan where all components are present 510 all_components_seen = AllComponentsSeen(mInfo); 511 if (!scan_to_display_first && all_components_seen) { 512 scan_to_display_first = mInfo.input_scan_number; 513 } 514 } 515 } while ((status != JPEG_SUSPENDED) && (status != JPEG_REACHED_EOI)); 516 517 if (!all_components_seen) { 518 return Transition::ContinueUnbuffered( 519 State::JPEG_DATA); // I/O suspension 520 } 521 // make sure we never try to access the non-exsitent scan 0 522 if (!scan_to_display_first) { 523 scan_to_display_first = 1; 524 } 525 while (mState != JPEG_DONE) { 526 if (mInfo.output_scanline == 0) { 527 int scan = mInfo.input_scan_number; 528 529 // if we haven't displayed anything yet (output_scan_number==0) 530 // and we have enough data for a complete scan, force output 531 // of the last full scan, but only if this last scan has seen 532 // DC data from all components 533 if ((mInfo.output_scan_number == 0) && 534 (scan > scan_to_display_first) && 535 (status != JPEG_REACHED_EOI)) { 536 scan--; 537 } 538 MOZ_ASSERT(scan > 0, "scan number to small!"); 539 if (!jpeg_start_output(&mInfo, scan)) { 540 MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug, 541 ("} (I/O suspension after jpeg_start_output() -" 542 " PROGRESSIVE)")); 543 return Transition::ContinueUnbuffered( 544 State::JPEG_DATA); // I/O suspension 545 } 546 } 547 548 if (mInfo.output_scanline == 0xffffff) { 549 mInfo.output_scanline = 0; 550 } 551 552 switch (OutputScanlines()) { 553 case WriteState::NEED_MORE_DATA: 554 if (mInfo.output_scanline == 0) { 555 // didn't manage to read any lines - flag so we don't call 556 // jpeg_start_output() multiple times for the same scan 557 mInfo.output_scanline = 0xffffff; 558 } 559 MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug, 560 ("} (I/O suspension after OutputScanlines() - " 561 "PROGRESSIVE)")); 562 return Transition::ContinueUnbuffered( 563 State::JPEG_DATA); // I/O suspension 564 case WriteState::FINISHED: 565 NS_ASSERTION(mInfo.output_scanline == mInfo.output_height, 566 "We didn't process all of the data!"); 567 568 if (!jpeg_finish_output(&mInfo)) { 569 MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug, 570 ("} (I/O suspension after jpeg_finish_output() -" 571 " PROGRESSIVE)")); 572 return Transition::ContinueUnbuffered( 573 State::JPEG_DATA); // I/O suspension 574 } 575 576 if (jpeg_input_complete(&mInfo) && 577 (mInfo.input_scan_number == mInfo.output_scan_number)) { 578 mState = JPEG_DONE; 579 } else { 580 mInfo.output_scanline = 0; 581 mPipe.ResetToFirstRow(); 582 } 583 break; 584 case WriteState::FAILURE: 585 mState = JPEG_ERROR; 586 MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug, 587 ("} (Error in pipeline from OutputScalines())")); 588 return Transition::TerminateFailure(); 589 } 590 } 591 } 592 [[fallthrough]]; // to finish decompressing. 593 } 594 595 case JPEG_DONE: { 596 LOG_SCOPE((mozilla::LogModule*)sJPEGLog, 597 "nsJPEGDecoder::ProcessData -- entering" 598 " JPEG_DONE case"); 599 600 // Step 7: Finish decompression 601 602 if (jpeg_finish_decompress(&mInfo) == FALSE) { 603 MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug, 604 ("} (I/O suspension after jpeg_finish_decompress() - DONE)")); 605 return Transition::ContinueUnbuffered( 606 State::JPEG_DATA); // I/O suspension 607 } 608 609 // Make sure we don't feed any more data to libjpeg-turbo. 610 mState = JPEG_SINK_NON_JPEG_TRAILER; 611 612 // We're done. 613 return Transition::TerminateSuccess(); 614 } 615 case JPEG_SINK_NON_JPEG_TRAILER: 616 MOZ_LOG(sJPEGLog, LogLevel::Debug, 617 ("[this=%p] nsJPEGDecoder::ProcessData -- entering" 618 " JPEG_SINK_NON_JPEG_TRAILER case\n", 619 this)); 620 621 MOZ_ASSERT_UNREACHABLE( 622 "Should stop getting data after entering state " 623 "JPEG_SINK_NON_JPEG_TRAILER"); 624 625 return Transition::TerminateSuccess(); 626 627 case JPEG_ERROR: 628 MOZ_ASSERT_UNREACHABLE( 629 "Should stop getting data after entering state " 630 "JPEG_ERROR"); 631 632 return Transition::TerminateFailure(); 633 } 634 635 MOZ_ASSERT_UNREACHABLE("Escaped the JPEG decoder state machine"); 636 return Transition::TerminateFailure(); 637 } // namespace image 638 639 LexerTransition<nsJPEGDecoder::State> nsJPEGDecoder::FinishedJPEGData() { 640 // Since we set up an unbuffered read for SIZE_MAX bytes, if we actually read 641 // all that data something is really wrong. 642 MOZ_ASSERT_UNREACHABLE("Read the entire address space?"); 643 return Transition::TerminateFailure(); 644 } 645 646 EXIFData nsJPEGDecoder::ReadExifData() const { 647 jpeg_saved_marker_ptr marker; 648 649 // Locate the APP1 marker, where EXIF data is stored, in the marker list. 650 for (marker = mInfo.marker_list; marker != nullptr; marker = marker->next) { 651 if (marker->marker == JPEG_APP0 + 1) { 652 break; 653 } 654 } 655 656 // If we're at the end of the list, there's no EXIF data. 657 if (!marker) { 658 return EXIFData(); 659 } 660 661 return EXIFParser::Parse(/* aExpectExifIdCode = */ true, marker->data, 662 static_cast<uint32_t>(marker->data_length), 663 gfx::IntSize(mInfo.image_width, mInfo.image_height)); 664 } 665 666 void nsJPEGDecoder::NotifyDone() { 667 PostFrameStop(Opacity::FULLY_OPAQUE); 668 PostDecodeDone(); 669 } 670 671 WriteState nsJPEGDecoder::OutputScanlines() { 672 auto result = mPipe.WritePixelBlocks<uint32_t>( 673 [&](uint32_t* aPixelBlock, int32_t aBlockSize) { 674 JSAMPROW sampleRow = (JSAMPROW)(mCMSLine ? mCMSLine : aPixelBlock); 675 if (jpeg_read_scanlines(&mInfo, &sampleRow, 1) != 1) { 676 return std::make_tuple(/* aWritten */ 0, 677 Some(WriteState::NEED_MORE_DATA)); 678 } 679 680 switch (mInfo.out_color_space) { 681 default: 682 // Already outputted directly to aPixelBlock as BGRA. 683 MOZ_ASSERT(!mCMSLine); 684 break; 685 case JCS_GRAYSCALE: 686 // The transform here does both color management, and converts the 687 // pixels from grayscale to BGRA. This is why we do it here, instead 688 // of using ColorManagementFilter in the SurfacePipe, because the 689 // other filters (e.g. DownscalingFilter) require BGRA pixels. 690 MOZ_ASSERT(mCMSLine); 691 qcms_transform_data(mTransform, mCMSLine, aPixelBlock, 692 mInfo.output_width); 693 break; 694 case JCS_CMYK: 695 // Convert from CMYK to BGRA 696 MOZ_ASSERT(mCMSLine); 697 cmyk_convert_bgra(mCMSLine, aPixelBlock, aBlockSize, mIsPDF); 698 break; 699 } 700 701 return std::make_tuple(aBlockSize, Maybe<WriteState>()); 702 }); 703 704 Maybe<SurfaceInvalidRect> invalidRect = mPipe.TakeInvalidRect(); 705 if (invalidRect) { 706 PostInvalidation(invalidRect->mInputSpaceRect, 707 Some(invalidRect->mOutputSpaceRect)); 708 } 709 710 return result; 711 } 712 713 // Override the standard error method in the IJG JPEG decoder code. 714 METHODDEF(void) 715 my_error_exit(j_common_ptr cinfo) { 716 decoder_error_mgr* err = (decoder_error_mgr*)cinfo->err; 717 718 // Convert error to a browser error code 719 nsresult error_code; 720 switch (err->pub.msg_code) { 721 case JERR_OUT_OF_MEMORY: 722 error_code = NS_ERROR_OUT_OF_MEMORY; 723 break; 724 case JERR_UNKNOWN_MARKER: 725 error_code = NS_ERROR_ILLEGAL_VALUE; 726 break; 727 case JERR_SOF_UNSUPPORTED: 728 error_code = NS_ERROR_INVALID_CONTENT_ENCODING; 729 break; 730 default: 731 error_code = NS_ERROR_FAILURE; 732 } 733 734 #ifdef DEBUG 735 char buffer[JMSG_LENGTH_MAX]; 736 737 // Create the message 738 (*err->pub.format_message)(cinfo, buffer); 739 740 fprintf(stderr, "JPEG decoding error:\n%s\n", buffer); 741 #endif 742 743 // Return control to the setjmp point. We pass an nsresult masquerading as 744 // an int, which works because the setjmp() caller casts it back. 745 longjmp(err->setjmp_buffer, static_cast<int>(error_code)); 746 } 747 748 static void progress_monitor(j_common_ptr info) { 749 int scan = ((j_decompress_ptr)info)->input_scan_number; 750 // Progressive images with a very large number of scans can cause the decoder 751 // to hang. Here we use the progress monitor to abort on a very large number 752 // of scans. 1000 is arbitrary, but much larger than the number of scans we 753 // might expect in a normal image. 754 if (scan >= 1000) { 755 my_error_exit(info); 756 } 757 } 758 759 /******************************************************************************* 760 * This is the callback routine from the IJG JPEG library used to supply new 761 * data to the decompressor when its input buffer is exhausted. It juggles 762 * multiple buffers in an attempt to avoid unnecessary copying of input data. 763 * 764 * (A simpler scheme is possible: It's much easier to use only a single 765 * buffer; when fill_input_buffer() is called, move any unconsumed data 766 * (beyond the current pointer/count) down to the beginning of this buffer and 767 * then load new data into the remaining buffer space. This approach requires 768 * a little more data copying but is far easier to get right.) 769 * 770 * At any one time, the JPEG decompressor is either reading from the necko 771 * input buffer, which is volatile across top-level calls to the IJG library, 772 * or the "backtrack" buffer. The backtrack buffer contains the remaining 773 * unconsumed data from the necko buffer after parsing was suspended due 774 * to insufficient data in some previous call to the IJG library. 775 * 776 * When suspending, the decompressor will back up to a convenient restart 777 * point (typically the start of the current MCU). The variables 778 * next_input_byte & bytes_in_buffer indicate where the restart point will be 779 * if the current call returns FALSE. Data beyond this point must be 780 * rescanned after resumption, so it must be preserved in case the decompressor 781 * decides to backtrack. 782 * 783 * Returns: 784 * TRUE if additional data is available, FALSE if no data present and 785 * the JPEG library should therefore suspend processing of input stream 786 ******************************************************************************/ 787 788 /******************************************************************************/ 789 /* data source manager method */ 790 /******************************************************************************/ 791 792 /******************************************************************************/ 793 /* data source manager method 794 Initialize source. This is called by jpeg_read_header() before any 795 data is actually read. May leave 796 bytes_in_buffer set to 0 (in which case a fill_input_buffer() call 797 will occur immediately). 798 */ 799 METHODDEF(void) 800 init_source(j_decompress_ptr jd) {} 801 802 /******************************************************************************/ 803 /* data source manager method 804 Skip num_bytes worth of data. The buffer pointer and count should 805 be advanced over num_bytes input bytes, refilling the buffer as 806 needed. This is used to skip over a potentially large amount of 807 uninteresting data (such as an APPn marker). In some applications 808 it may be possible to optimize away the reading of the skipped data, 809 but it's not clear that being smart is worth much trouble; large 810 skips are uncommon. bytes_in_buffer may be zero on return. 811 A zero or negative skip count should be treated as a no-op. 812 */ 813 METHODDEF(void) 814 skip_input_data(j_decompress_ptr jd, long num_bytes) { 815 struct jpeg_source_mgr* src = jd->src; 816 nsJPEGDecoder* decoder = (nsJPEGDecoder*)(jd->client_data); 817 818 if (num_bytes > (long)src->bytes_in_buffer) { 819 // Can't skip it all right now until we get more data from 820 // network stream. Set things up so that fill_input_buffer 821 // will skip remaining amount. 822 decoder->mBytesToSkip = (size_t)num_bytes - src->bytes_in_buffer; 823 src->next_input_byte += src->bytes_in_buffer; 824 src->bytes_in_buffer = 0; 825 826 } else { 827 // Simple case. Just advance buffer pointer 828 829 src->bytes_in_buffer -= (size_t)num_bytes; 830 src->next_input_byte += num_bytes; 831 } 832 } 833 834 /******************************************************************************/ 835 /* data source manager method 836 This is called whenever bytes_in_buffer has reached zero and more 837 data is wanted. In typical applications, it should read fresh data 838 into the buffer (ignoring the current state of next_input_byte and 839 bytes_in_buffer), reset the pointer & count to the start of the 840 buffer, and return TRUE indicating that the buffer has been reloaded. 841 It is not necessary to fill the buffer entirely, only to obtain at 842 least one more byte. bytes_in_buffer MUST be set to a positive value 843 if TRUE is returned. A FALSE return should only be used when I/O 844 suspension is desired. 845 */ 846 METHODDEF(boolean) 847 fill_input_buffer(j_decompress_ptr jd) { 848 struct jpeg_source_mgr* src = jd->src; 849 nsJPEGDecoder* decoder = (nsJPEGDecoder*)(jd->client_data); 850 851 if (decoder->mReading) { 852 const JOCTET* new_buffer = decoder->mSegment; 853 uint32_t new_buflen = decoder->mSegmentLen; 854 855 if (!new_buffer || new_buflen == 0) { 856 return false; // suspend 857 } 858 859 decoder->mSegmentLen = 0; 860 861 if (decoder->mBytesToSkip) { 862 if (decoder->mBytesToSkip < new_buflen) { 863 // All done skipping bytes; Return what's left. 864 new_buffer += decoder->mBytesToSkip; 865 new_buflen -= decoder->mBytesToSkip; 866 decoder->mBytesToSkip = 0; 867 } else { 868 // Still need to skip some more data in the future 869 decoder->mBytesToSkip -= (size_t)new_buflen; 870 return false; // suspend 871 } 872 } 873 874 decoder->mBackBufferUnreadLen = src->bytes_in_buffer; 875 876 src->next_input_byte = new_buffer; 877 src->bytes_in_buffer = (size_t)new_buflen; 878 decoder->mReading = false; 879 880 return true; 881 } 882 883 if (src->next_input_byte != decoder->mSegment) { 884 // Backtrack data has been permanently consumed. 885 decoder->mBackBufferUnreadLen = 0; 886 decoder->mBackBufferLen = 0; 887 } 888 889 // Save remainder of netlib buffer in backtrack buffer 890 const uint32_t new_backtrack_buflen = 891 src->bytes_in_buffer + decoder->mBackBufferLen; 892 893 // Make sure backtrack buffer is big enough to hold new data. 894 if (decoder->mBackBufferSize < new_backtrack_buflen) { 895 // Check for malformed MARKER segment lengths, before allocating space 896 // for it 897 if (new_backtrack_buflen > MAX_JPEG_MARKER_LENGTH) { 898 my_error_exit((j_common_ptr)(&decoder->mInfo)); 899 } 900 901 // Round up to multiple of 256 bytes. 902 const size_t roundup_buflen = ((new_backtrack_buflen + 255) >> 8) << 8; 903 JOCTET* buf = (JOCTET*)realloc(decoder->mBackBuffer, roundup_buflen); 904 // Check for OOM 905 if (!buf) { 906 decoder->mInfo.err->msg_code = JERR_OUT_OF_MEMORY; 907 my_error_exit((j_common_ptr)(&decoder->mInfo)); 908 } 909 decoder->mBackBuffer = buf; 910 decoder->mBackBufferSize = roundup_buflen; 911 } 912 913 // Ensure we actually have a backtrack buffer. Without it, then we know that 914 // there is no data to copy and bytes_in_buffer is already zero. 915 if (decoder->mBackBuffer) { 916 // Copy remainder of netlib segment into backtrack buffer. 917 memmove(decoder->mBackBuffer + decoder->mBackBufferLen, 918 src->next_input_byte, src->bytes_in_buffer); 919 } else { 920 MOZ_ASSERT(src->bytes_in_buffer == 0); 921 MOZ_ASSERT(decoder->mBackBufferLen == 0); 922 MOZ_ASSERT(decoder->mBackBufferUnreadLen == 0); 923 } 924 925 // Point to start of data to be rescanned. 926 src->next_input_byte = decoder->mBackBuffer + decoder->mBackBufferLen - 927 decoder->mBackBufferUnreadLen; 928 src->bytes_in_buffer += decoder->mBackBufferUnreadLen; 929 decoder->mBackBufferLen = (size_t)new_backtrack_buflen; 930 decoder->mReading = true; 931 932 return false; 933 } 934 935 /******************************************************************************/ 936 /* data source manager method */ 937 /* 938 * Terminate source --- called by jpeg_finish_decompress() after all 939 * data has been read to clean up JPEG source manager. NOT called by 940 * jpeg_abort() or jpeg_destroy(). 941 */ 942 METHODDEF(void) 943 term_source(j_decompress_ptr jd) { 944 nsJPEGDecoder* decoder = (nsJPEGDecoder*)(jd->client_data); 945 946 // This function shouldn't be called if we ran into an error we didn't 947 // recover from. 948 MOZ_ASSERT(decoder->mState != JPEG_ERROR, 949 "Calling term_source on a JPEG with mState == JPEG_ERROR!"); 950 951 // Notify using a helper method to get around protectedness issues. 952 decoder->NotifyDone(); 953 } 954 955 } // namespace image 956 } // namespace mozilla 957 958 ///*************** Inverted CMYK -> RGB conversion ************************* 959 /// Input is (Inverted) CMYK stored as 4 bytes per pixel. 960 /// Output is RGB stored as 3 bytes per pixel. 961 /// @param aInput Points to row buffer containing the CMYK bytes for each pixel 962 /// in the row. 963 /// @param aOutput Points to row buffer to write BGRA to. 964 /// @param aWidth Number of pixels in the row. 965 static void cmyk_convert_bgra(uint32_t* aInput, uint32_t* aOutput, 966 int32_t aWidth, bool aIsInverted) { 967 uint8_t* input = reinterpret_cast<uint8_t*>(aInput); 968 969 for (int32_t i = 0; i < aWidth; ++i) { 970 // Source is 'Inverted CMYK', output is RGB. 971 // See: http://www.easyrgb.com/math.php?MATH=M12#text12 972 // Or: http://www.ilkeratalay.com/colorspacesfaq.php#rgb 973 974 // From CMYK to CMY 975 // C = ( C * ( 1 - K ) + K ) 976 // M = ( M * ( 1 - K ) + K ) 977 // Y = ( Y * ( 1 - K ) + K ) 978 979 // From Inverted CMYK to CMY is thus: 980 // C = ( (1-iC) * (1 - (1-iK)) + (1-iK) ) => 1 - iC*iK 981 // Same for M and Y 982 983 // Convert from CMY (0..1) to RGB (0..1) 984 // R = 1 - C => 1 - (1 - iC*iK) => iC*iK 985 // G = 1 - M => 1 - (1 - iM*iK) => iM*iK 986 // B = 1 - Y => 1 - (1 - iY*iK) => iY*iK 987 988 // Convert from Inverted CMYK (0..255) to RGB (0..255) 989 uint32_t iC = input[0]; 990 uint32_t iM = input[1]; 991 uint32_t iY = input[2]; 992 uint32_t iK = input[3]; 993 if (MOZ_UNLIKELY(aIsInverted)) { 994 iC = 255 - iC; 995 iM = 255 - iM; 996 iY = 255 - iY; 997 iK = 255 - iK; 998 } 999 1000 const uint8_t r = iC * iK / 255; 1001 const uint8_t g = iM * iK / 255; 1002 const uint8_t b = iY * iK / 255; 1003 1004 *aOutput++ = (0xFF << mozilla::gfx::SurfaceFormatBit::OS_A) | 1005 (r << mozilla::gfx::SurfaceFormatBit::OS_R) | 1006 (g << mozilla::gfx::SurfaceFormatBit::OS_G) | 1007 (b << mozilla::gfx::SurfaceFormatBit::OS_B); 1008 input += 4; 1009 } 1010 }