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