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
17 #include "nsIInputStream.h"
18
19 #include "nspr.h"
20 #include "nsCRT.h"
21 #include "gfxColor.h"
22
23 #include "jerror.h"
24
25 #include "gfxPlatform.h"
26 #include "mozilla/EndianUtils.h"
27 #include "mozilla/Telemetry.h"
28
29 extern "C" {
30 #include "iccjpeg.h"
31
32 #ifdef JCS_EXTENSIONS
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 #else
39 /* Colorspace conversion (copied from jpegint.h) */
40 struct jpeg_color_deconverter {
41 JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
42 JMETHOD(void, color_convert, (j_decompress_ptr cinfo,
43 JSAMPIMAGE input_buf, JDIMENSION input_row,
44 JSAMPARRAY output_buf, int num_rows));
45 };
46
47 METHODDEF(void)
48 ycc_rgb_convert_argb (j_decompress_ptr cinfo,
49 JSAMPIMAGE input_buf, JDIMENSION input_row,
50 JSAMPARRAY output_buf, int num_rows);
51 #endif
52 }
53
54 static void cmyk_convert_rgb(JSAMPROW row, JDIMENSION width);
55
56 namespace mozilla {
57 namespace image {
58
59 static mozilla::LazyLogModule sJPEGLog("JPEGDecoder");
60
61 static mozilla::LazyLogModule sJPEGDecoderAccountingLog("JPEGDecoderAccounting");
62
63 static qcms_profile*
GetICCProfile(struct jpeg_decompress_struct & info)64 GetICCProfile(struct jpeg_decompress_struct& info)
65 {
66 JOCTET* profilebuf;
67 uint32_t profileLength;
68 qcms_profile* profile = nullptr;
69
70 if (read_icc_profile(&info, &profilebuf, &profileLength)) {
71 profile = qcms_profile_from_memory(profilebuf, profileLength);
72 free(profilebuf);
73 }
74
75 return profile;
76 }
77
78 METHODDEF(void) init_source (j_decompress_ptr jd);
79 METHODDEF(boolean) fill_input_buffer (j_decompress_ptr jd);
80 METHODDEF(void) skip_input_data (j_decompress_ptr jd, long num_bytes);
81 METHODDEF(void) term_source (j_decompress_ptr jd);
82 METHODDEF(void) my_error_exit (j_common_ptr cinfo);
83
84 // Normal JFIF markers can't have more bytes than this.
85 #define MAX_JPEG_MARKER_LENGTH (((uint32_t)1 << 16) - 1)
86
nsJPEGDecoder(RasterImage * aImage,Decoder::DecodeStyle aDecodeStyle)87 nsJPEGDecoder::nsJPEGDecoder(RasterImage* aImage,
88 Decoder::DecodeStyle aDecodeStyle)
89 : Decoder(aImage)
90 , mLexer(Transition::ToUnbuffered(State::FINISHED_JPEG_DATA,
91 State::JPEG_DATA,
92 SIZE_MAX),
93 Transition::TerminateSuccess())
94 , mDecodeStyle(aDecodeStyle)
95 , mSampleSize(0)
96 {
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 mInProfile = nullptr;
113 mTransform = nullptr;
114
115 mCMSMode = 0;
116
117 MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
118 ("nsJPEGDecoder::nsJPEGDecoder: Creating JPEG decoder %p",
119 this));
120 }
121
~nsJPEGDecoder()122 nsJPEGDecoder::~nsJPEGDecoder()
123 {
124 // Step 8: Release JPEG decompression object
125 mInfo.src = nullptr;
126 jpeg_destroy_decompress(&mInfo);
127
128 PR_FREEIF(mBackBuffer);
129 if (mTransform) {
130 qcms_transform_release(mTransform);
131 }
132 if (mInProfile) {
133 qcms_profile_release(mInProfile);
134 }
135
136 MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
137 ("nsJPEGDecoder::~nsJPEGDecoder: Destroying JPEG decoder %p",
138 this));
139 }
140
141 Maybe<Telemetry::ID>
SpeedHistogram() const142 nsJPEGDecoder::SpeedHistogram() const
143 {
144 return Some(Telemetry::IMAGE_DECODE_SPEED_JPEG);
145 }
146
147 nsresult
InitInternal()148 nsJPEGDecoder::InitInternal()
149 {
150 mCMSMode = gfxPlatform::GetCMSMode();
151 if (GetSurfaceFlags() & SurfaceFlags::NO_COLORSPACE_CONVERSION) {
152 mCMSMode = eCMSMode_Off;
153 }
154
155 // We set up the normal JPEG error routines, then override error_exit.
156 mInfo.err = jpeg_std_error(&mErr.pub);
157 // mInfo.err = jpeg_std_error(&mErr.pub);
158 mErr.pub.error_exit = my_error_exit;
159 // Establish the setjmp return context for my_error_exit to use.
160 if (setjmp(mErr.setjmp_buffer)) {
161 // If we get here, the JPEG code has signaled an error, and initialization
162 // has failed.
163 return NS_ERROR_FAILURE;
164 }
165
166 // Step 1: allocate and initialize JPEG decompression object
167 jpeg_create_decompress(&mInfo);
168 // Set the source manager
169 mInfo.src = &mSourceMgr;
170
171 // Step 2: specify data source (eg, a file)
172
173 // Setup callback functions.
174 mSourceMgr.init_source = init_source;
175 mSourceMgr.fill_input_buffer = fill_input_buffer;
176 mSourceMgr.skip_input_data = skip_input_data;
177 mSourceMgr.resync_to_restart = jpeg_resync_to_restart;
178 mSourceMgr.term_source = term_source;
179
180 // Record app markers for ICC data
181 for (uint32_t m = 0; m < 16; m++) {
182 jpeg_save_markers(&mInfo, JPEG_APP0 + m, 0xFFFF);
183 }
184
185 return NS_OK;
186 }
187
188 nsresult
FinishInternal()189 nsJPEGDecoder::FinishInternal()
190 {
191 // If we're not in any sort of error case, force our state to JPEG_DONE.
192 if ((mState != JPEG_DONE && mState != JPEG_SINK_NON_JPEG_TRAILER) &&
193 (mState != JPEG_ERROR) &&
194 !IsMetadataDecode()) {
195 mState = JPEG_DONE;
196 }
197
198 return NS_OK;
199 }
200
201 LexerResult
DoDecode(SourceBufferIterator & aIterator,IResumable * aOnResume)202 nsJPEGDecoder::DoDecode(SourceBufferIterator& aIterator, IResumable* aOnResume)
203 {
204 MOZ_ASSERT(!HasError(), "Shouldn't call DoDecode after error!");
205
206 return mLexer.Lex(aIterator, aOnResume,
207 [=](State aState, const char* aData, size_t aLength) {
208 switch (aState) {
209 case State::JPEG_DATA:
210 return ReadJPEGData(aData, aLength);
211 case State::FINISHED_JPEG_DATA:
212 return FinishedJPEGData();
213 }
214 MOZ_CRASH("Unknown State");
215 });
216 }
217
218 LexerTransition<nsJPEGDecoder::State>
ReadJPEGData(const char * aData,size_t aLength)219 nsJPEGDecoder::ReadJPEGData(const char* aData, size_t aLength)
220 {
221 mSegment = reinterpret_cast<const JOCTET*>(aData);
222 mSegmentLen = aLength;
223
224 // Return here if there is a fatal error within libjpeg.
225 nsresult error_code;
226 // This cast to nsresult makes sense because setjmp() returns whatever we
227 // passed to longjmp(), which was actually an nsresult.
228 if ((error_code = static_cast<nsresult>(setjmp(mErr.setjmp_buffer))) != NS_OK) {
229 if (error_code == NS_ERROR_FAILURE) {
230 // Error due to corrupt data. Make sure that we don't feed any more data
231 // to libjpeg-turbo.
232 mState = JPEG_SINK_NON_JPEG_TRAILER;
233 MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
234 ("} (setjmp returned NS_ERROR_FAILURE)"));
235 } else {
236 // Error for another reason. (Possibly OOM.)
237 mState = JPEG_ERROR;
238 MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
239 ("} (setjmp returned an error)"));
240 }
241
242 return Transition::TerminateFailure();
243 }
244
245 MOZ_LOG(sJPEGLog, LogLevel::Debug,
246 ("[this=%p] nsJPEGDecoder::Write -- processing JPEG data\n", this));
247
248 switch (mState) {
249 case JPEG_HEADER: {
250 LOG_SCOPE((mozilla::LogModule*)sJPEGLog, "nsJPEGDecoder::Write -- entering JPEG_HEADER"
251 " case");
252
253 // Step 3: read file parameters with jpeg_read_header()
254 if (jpeg_read_header(&mInfo, TRUE) == JPEG_SUSPENDED) {
255 MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
256 ("} (JPEG_SUSPENDED)"));
257 return Transition::ContinueUnbuffered(State::JPEG_DATA); // I/O suspension
258 }
259
260 // If we have a sample size specified for -moz-sample-size, use it.
261 if (mSampleSize > 0) {
262 mInfo.scale_num = 1;
263 mInfo.scale_denom = mSampleSize;
264 }
265
266 // Used to set up image size so arrays can be allocated
267 jpeg_calc_output_dimensions(&mInfo);
268
269 // Post our size to the superclass
270 PostSize(mInfo.output_width, mInfo.output_height,
271 ReadOrientationFromEXIF());
272 if (HasError()) {
273 // Setting the size led to an error.
274 mState = JPEG_ERROR;
275 return Transition::TerminateFailure();
276 }
277
278 // If we're doing a metadata decode, we're done.
279 if (IsMetadataDecode()) {
280 return Transition::TerminateSuccess();
281 }
282
283 // We're doing a full decode.
284 if (mCMSMode != eCMSMode_Off &&
285 (mInProfile = GetICCProfile(mInfo)) != nullptr) {
286 uint32_t profileSpace = qcms_profile_get_color_space(mInProfile);
287 bool mismatch = false;
288
289 #ifdef DEBUG_tor
290 fprintf(stderr, "JPEG profileSpace: 0x%08X\n", profileSpace);
291 #endif
292 switch (mInfo.jpeg_color_space) {
293 case JCS_GRAYSCALE:
294 if (profileSpace == icSigRgbData) {
295 mInfo.out_color_space = JCS_RGB;
296 } else if (profileSpace != icSigGrayData) {
297 mismatch = true;
298 }
299 break;
300 case JCS_RGB:
301 if (profileSpace != icSigRgbData) {
302 mismatch = true;
303 }
304 break;
305 case JCS_YCbCr:
306 if (profileSpace == icSigRgbData) {
307 mInfo.out_color_space = JCS_RGB;
308 } else {
309 // qcms doesn't support ycbcr
310 mismatch = true;
311 }
312 break;
313 case JCS_CMYK:
314 case JCS_YCCK:
315 // qcms doesn't support cmyk
316 mismatch = true;
317 break;
318 default:
319 mState = JPEG_ERROR;
320 MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
321 ("} (unknown colorpsace (1))"));
322 return Transition::TerminateFailure();
323 }
324
325 if (!mismatch) {
326 qcms_data_type type;
327 switch (mInfo.out_color_space) {
328 case JCS_GRAYSCALE:
329 type = QCMS_DATA_GRAY_8;
330 break;
331 case JCS_RGB:
332 type = QCMS_DATA_RGB_8;
333 break;
334 default:
335 mState = JPEG_ERROR;
336 MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
337 ("} (unknown colorpsace (2))"));
338 return Transition::TerminateFailure();
339 }
340 #if 0
341 // We don't currently support CMYK profiles. The following
342 // code dealt with lcms types. Add something like this
343 // back when we gain support for CMYK.
344
345 // Adobe Photoshop writes YCCK/CMYK files with inverted data
346 if (mInfo.out_color_space == JCS_CMYK) {
347 type |= FLAVOR_SH(mInfo.saw_Adobe_marker ? 1 : 0);
348 }
349 #endif
350
351 if (gfxPlatform::GetCMSOutputProfile()) {
352
353 // Calculate rendering intent.
354 int intent = gfxPlatform::GetRenderingIntent();
355 if (intent == -1) {
356 intent = qcms_profile_get_rendering_intent(mInProfile);
357 }
358
359 // Create the color management transform.
360 mTransform = qcms_transform_create(mInProfile,
361 type,
362 gfxPlatform::GetCMSOutputProfile(),
363 QCMS_DATA_RGB_8,
364 (qcms_intent)intent);
365 }
366 } else {
367 #ifdef DEBUG_tor
368 fprintf(stderr, "ICM profile colorspace mismatch\n");
369 #endif
370 }
371 }
372
373 if (!mTransform) {
374 switch (mInfo.jpeg_color_space) {
375 case JCS_GRAYSCALE:
376 case JCS_RGB:
377 case JCS_YCbCr:
378 #ifdef JCS_EXTENSIONS
379 // if we're not color managing we can decode directly to
380 // MOZ_JCS_EXT_NATIVE_ENDIAN_XRGB
381 if (mCMSMode != eCMSMode_All) {
382 mInfo.out_color_space = MOZ_JCS_EXT_NATIVE_ENDIAN_XRGB;
383 mInfo.out_color_components = 4;
384 } else {
385 mInfo.out_color_space = JCS_RGB;
386 }
387 #else
388 mInfo.out_color_space = JCS_RGB;
389 #endif
390 break;
391 case JCS_CMYK:
392 case JCS_YCCK:
393 // libjpeg can convert from YCCK to CMYK, but not to RGB
394 mInfo.out_color_space = JCS_CMYK;
395 break;
396 default:
397 mState = JPEG_ERROR;
398 MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
399 ("} (unknown colorpsace (3))"));
400 return Transition::TerminateFailure();
401 }
402 }
403
404 // Don't allocate a giant and superfluous memory buffer
405 // when not doing a progressive decode.
406 mInfo.buffered_image = mDecodeStyle == PROGRESSIVE &&
407 jpeg_has_multiple_scans(&mInfo);
408
409 MOZ_ASSERT(!mImageData, "Already have a buffer allocated?");
410 nsresult rv = AllocateFrame(/* aFrameNum = */ 0, OutputSize(),
411 FullOutputFrame(), SurfaceFormat::B8G8R8X8);
412 if (NS_FAILED(rv)) {
413 mState = JPEG_ERROR;
414 MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
415 ("} (could not initialize image frame)"));
416 return Transition::TerminateFailure();
417 }
418
419 MOZ_ASSERT(mImageData, "Should have a buffer now");
420
421 if (mDownscaler) {
422 nsresult rv = mDownscaler->BeginFrame(Size(), Nothing(),
423 mImageData,
424 /* aHasAlpha = */ false);
425 if (NS_FAILED(rv)) {
426 mState = JPEG_ERROR;
427 return Transition::TerminateFailure();
428 }
429 }
430
431 MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
432 (" JPEGDecoderAccounting: nsJPEGDecoder::"
433 "Write -- created image frame with %ux%u pixels",
434 mInfo.output_width, mInfo.output_height));
435
436 mState = JPEG_START_DECOMPRESS;
437 MOZ_FALLTHROUGH; // to start decompressing.
438 }
439
440 case JPEG_START_DECOMPRESS: {
441 LOG_SCOPE((mozilla::LogModule*)sJPEGLog, "nsJPEGDecoder::Write -- entering"
442 " JPEG_START_DECOMPRESS case");
443 // Step 4: set parameters for decompression
444
445 // FIXME -- Should reset dct_method and dither mode
446 // for final pass of progressive JPEG
447
448 mInfo.dct_method = JDCT_ISLOW;
449 mInfo.dither_mode = JDITHER_FS;
450 mInfo.do_fancy_upsampling = TRUE;
451 mInfo.enable_2pass_quant = FALSE;
452 mInfo.do_block_smoothing = TRUE;
453
454 // Step 5: Start decompressor
455 if (jpeg_start_decompress(&mInfo) == FALSE) {
456 MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
457 ("} (I/O suspension after jpeg_start_decompress())"));
458 return Transition::ContinueUnbuffered(State::JPEG_DATA); // I/O suspension
459 }
460
461 #ifndef JCS_EXTENSIONS
462 /* Force to use our YCbCr to Packed RGB converter when possible */
463 if (!mTransform && (mCMSMode != eCMSMode_All) &&
464 mInfo.jpeg_color_space == JCS_YCbCr && mInfo.out_color_space == JCS_RGB) {
465 /* Special case for the most common case: transform from YCbCr direct into packed ARGB */
466 mInfo.out_color_components = 4; /* Packed ARGB pixels are always 4 bytes...*/
467 mInfo.cconvert->color_convert = ycc_rgb_convert_argb;
468 }
469 #endif
470
471 // If this is a progressive JPEG ...
472 mState = mInfo.buffered_image ?
473 JPEG_DECOMPRESS_PROGRESSIVE : JPEG_DECOMPRESS_SEQUENTIAL;
474 MOZ_FALLTHROUGH; // to decompress sequential JPEG.
475 }
476
477 case JPEG_DECOMPRESS_SEQUENTIAL: {
478 if (mState == JPEG_DECOMPRESS_SEQUENTIAL) {
479 LOG_SCOPE((mozilla::LogModule*)sJPEGLog, "nsJPEGDecoder::Write -- "
480 "JPEG_DECOMPRESS_SEQUENTIAL case");
481
482 bool suspend;
483 OutputScanlines(&suspend);
484
485 if (suspend) {
486 MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
487 ("} (I/O suspension after OutputScanlines() - SEQUENTIAL)"));
488 return Transition::ContinueUnbuffered(State::JPEG_DATA); // I/O suspension
489 }
490
491 // If we've completed image output ...
492 NS_ASSERTION(mInfo.output_scanline == mInfo.output_height,
493 "We didn't process all of the data!");
494 mState = JPEG_DONE;
495 }
496 MOZ_FALLTHROUGH; // to decompress progressive JPEG.
497 }
498
499 case JPEG_DECOMPRESS_PROGRESSIVE: {
500 if (mState == JPEG_DECOMPRESS_PROGRESSIVE) {
501 LOG_SCOPE((mozilla::LogModule*)sJPEGLog,
502 "nsJPEGDecoder::Write -- JPEG_DECOMPRESS_PROGRESSIVE case");
503
504 int status;
505 do {
506 status = jpeg_consume_input(&mInfo);
507 } while ((status != JPEG_SUSPENDED) &&
508 (status != JPEG_REACHED_EOI));
509
510 for (;;) {
511 if (mInfo.output_scanline == 0) {
512 int scan = mInfo.input_scan_number;
513
514 // if we haven't displayed anything yet (output_scan_number==0)
515 // and we have enough data for a complete scan, force output
516 // of the last full scan
517 if ((mInfo.output_scan_number == 0) &&
518 (scan > 1) &&
519 (status != JPEG_REACHED_EOI))
520 scan--;
521
522 if (!jpeg_start_output(&mInfo, scan)) {
523 MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
524 ("} (I/O suspension after jpeg_start_output() -"
525 " PROGRESSIVE)"));
526 return Transition::ContinueUnbuffered(State::JPEG_DATA); // I/O suspension
527 }
528 }
529
530 if (mInfo.output_scanline == 0xffffff) {
531 mInfo.output_scanline = 0;
532 }
533
534 bool suspend;
535 OutputScanlines(&suspend);
536
537 if (suspend) {
538 if (mInfo.output_scanline == 0) {
539 // didn't manage to read any lines - flag so we don't call
540 // jpeg_start_output() multiple times for the same scan
541 mInfo.output_scanline = 0xffffff;
542 }
543 MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
544 ("} (I/O suspension after OutputScanlines() - PROGRESSIVE)"));
545 return Transition::ContinueUnbuffered(State::JPEG_DATA); // I/O suspension
546 }
547
548 if (mInfo.output_scanline == mInfo.output_height) {
549 if (!jpeg_finish_output(&mInfo)) {
550 MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
551 ("} (I/O suspension after jpeg_finish_output() -"
552 " PROGRESSIVE)"));
553 return Transition::ContinueUnbuffered(State::JPEG_DATA); // I/O suspension
554 }
555
556 if (jpeg_input_complete(&mInfo) &&
557 (mInfo.input_scan_number == mInfo.output_scan_number))
558 break;
559
560 mInfo.output_scanline = 0;
561 if (mDownscaler) {
562 mDownscaler->ResetForNextProgressivePass();
563 }
564 }
565 }
566
567 mState = JPEG_DONE;
568 }
569 MOZ_FALLTHROUGH; // to finish decompressing.
570 }
571
572 case JPEG_DONE: {
573 LOG_SCOPE((mozilla::LogModule*)sJPEGLog, "nsJPEGDecoder::ProcessData -- entering"
574 " JPEG_DONE case");
575
576 // Step 7: Finish decompression
577
578 if (jpeg_finish_decompress(&mInfo) == FALSE) {
579 MOZ_LOG(sJPEGDecoderAccountingLog, LogLevel::Debug,
580 ("} (I/O suspension after jpeg_finish_decompress() - DONE)"));
581 return Transition::ContinueUnbuffered(State::JPEG_DATA); // I/O suspension
582 }
583
584 // Make sure we don't feed any more data to libjpeg-turbo.
585 mState = JPEG_SINK_NON_JPEG_TRAILER;
586
587 // We're done.
588 return Transition::TerminateSuccess();
589 }
590 case JPEG_SINK_NON_JPEG_TRAILER:
591 MOZ_LOG(sJPEGLog, LogLevel::Debug,
592 ("[this=%p] nsJPEGDecoder::ProcessData -- entering"
593 " JPEG_SINK_NON_JPEG_TRAILER case\n", this));
594
595 MOZ_ASSERT_UNREACHABLE("Should stop getting data after entering state "
596 "JPEG_SINK_NON_JPEG_TRAILER");
597
598 return Transition::TerminateSuccess();
599
600 case JPEG_ERROR:
601 MOZ_ASSERT_UNREACHABLE("Should stop getting data after entering state "
602 "JPEG_ERROR");
603
604 return Transition::TerminateFailure();
605 }
606
607 MOZ_ASSERT_UNREACHABLE("Escaped the JPEG decoder state machine");
608 return Transition::TerminateFailure();
609 }
610
611 LexerTransition<nsJPEGDecoder::State>
FinishedJPEGData()612 nsJPEGDecoder::FinishedJPEGData()
613 {
614 // Since we set up an unbuffered read for SIZE_MAX bytes, if we actually read
615 // all that data something is really wrong.
616 MOZ_ASSERT_UNREACHABLE("Read the entire address space?");
617 return Transition::TerminateFailure();
618 }
619
620 Orientation
ReadOrientationFromEXIF()621 nsJPEGDecoder::ReadOrientationFromEXIF()
622 {
623 jpeg_saved_marker_ptr marker;
624
625 // Locate the APP1 marker, where EXIF data is stored, in the marker list.
626 for (marker = mInfo.marker_list ; marker != nullptr ; marker = marker->next) {
627 if (marker->marker == JPEG_APP0 + 1) {
628 break;
629 }
630 }
631
632 // If we're at the end of the list, there's no EXIF data.
633 if (!marker) {
634 return Orientation();
635 }
636
637 // Extract the orientation information.
638 EXIFData exif = EXIFParser::Parse(marker->data,
639 static_cast<uint32_t>(marker->data_length));
640 return exif.orientation;
641 }
642
643 void
NotifyDone()644 nsJPEGDecoder::NotifyDone()
645 {
646 PostFrameStop(Opacity::FULLY_OPAQUE);
647 PostDecodeDone();
648 }
649
650 void
OutputScanlines(bool * suspend)651 nsJPEGDecoder::OutputScanlines(bool* suspend)
652 {
653 *suspend = false;
654
655 const uint32_t top = mInfo.output_scanline;
656
657 while ((mInfo.output_scanline < mInfo.output_height)) {
658 uint32_t* imageRow = nullptr;
659 if (mDownscaler) {
660 imageRow = reinterpret_cast<uint32_t*>(mDownscaler->RowBuffer());
661 } else {
662 imageRow = reinterpret_cast<uint32_t*>(mImageData) +
663 (mInfo.output_scanline * mInfo.output_width);
664 }
665
666 MOZ_ASSERT(imageRow, "Should have a row buffer here");
667
668 #ifdef JCS_EXTENSIONS
669 if (mInfo.out_color_space == MOZ_JCS_EXT_NATIVE_ENDIAN_XRGB) {
670 #else
671 if (mInfo.cconvert->color_convert == ycc_rgb_convert_argb) {
672 #endif
673 // Special case: scanline will be directly converted into packed ARGB
674 if (jpeg_read_scanlines(&mInfo, (JSAMPARRAY)&imageRow, 1) != 1) {
675 *suspend = true; // suspend
676 break;
677 }
678 if (mDownscaler) {
679 mDownscaler->CommitRow();
680 }
681 continue; // all done for this row!
682 }
683
684 JSAMPROW sampleRow = (JSAMPROW)imageRow;
685 if (mInfo.output_components == 3) {
686 // Put the pixels at end of row to enable in-place expansion
687 sampleRow += mInfo.output_width;
688 }
689
690 // Request one scanline. Returns 0 or 1 scanlines.
691 if (jpeg_read_scanlines(&mInfo, &sampleRow, 1) != 1) {
692 *suspend = true; // suspend
693 break;
694 }
695
696 if (mTransform) {
697 JSAMPROW source = sampleRow;
698 if (mInfo.out_color_space == JCS_GRAYSCALE) {
699 // Convert from the 1byte grey pixels at begin of row
700 // to the 3byte RGB byte pixels at 'end' of row
701 sampleRow += mInfo.output_width;
702 }
703 qcms_transform_data(mTransform, source, sampleRow, mInfo.output_width);
704 // Move 3byte RGB data to end of row
705 if (mInfo.out_color_space == JCS_CMYK) {
706 memmove(sampleRow + mInfo.output_width,
707 sampleRow,
708 3 * mInfo.output_width);
709 sampleRow += mInfo.output_width;
710 }
711 } else {
712 if (mInfo.out_color_space == JCS_CMYK) {
713 // Convert from CMYK to RGB
714 // We cannot convert directly to Cairo, as the CMSRGBTransform
715 // may wants to do a RGB transform...
716 // Would be better to have platform CMSenabled transformation
717 // from CMYK to (A)RGB...
718 cmyk_convert_rgb((JSAMPROW)imageRow, mInfo.output_width);
719 sampleRow += mInfo.output_width;
720 }
721 if (mCMSMode == eCMSMode_All) {
722 // No embedded ICC profile - treat as sRGB
723 qcms_transform* transform = gfxPlatform::GetCMSRGBTransform();
724 if (transform) {
725 qcms_transform_data(transform, sampleRow, sampleRow,
726 mInfo.output_width);
727 }
728 }
729 }
730
731 // counter for while() loops below
732 uint32_t idx = mInfo.output_width;
733
734 // copy as bytes until source pointer is 32-bit-aligned
735 for (; (NS_PTR_TO_UINT32(sampleRow) & 0x3) && idx; --idx) {
736 *imageRow++ = gfxPackedPixel(0xFF, sampleRow[0], sampleRow[1],
737 sampleRow[2]);
738 sampleRow += 3;
739 }
740
741 // copy pixels in blocks of 4
742 while (idx >= 4) {
743 GFX_BLOCK_RGB_TO_FRGB(sampleRow, imageRow);
744 idx -= 4;
745 sampleRow += 12;
746 imageRow += 4;
747 }
748
749 // copy remaining pixel(s)
750 while (idx--) {
751 // 32-bit read of final pixel will exceed buffer, so read bytes
752 *imageRow++ = gfxPackedPixel(0xFF, sampleRow[0], sampleRow[1],
753 sampleRow[2]);
754 sampleRow += 3;
755 }
756
757 if (mDownscaler) {
758 mDownscaler->CommitRow();
759 }
760 }
761
762 if (mDownscaler && mDownscaler->HasInvalidation()) {
763 DownscalerInvalidRect invalidRect = mDownscaler->TakeInvalidRect();
764 PostInvalidation(invalidRect.mOriginalSizeRect,
765 Some(invalidRect.mTargetSizeRect));
766 MOZ_ASSERT(!mDownscaler->HasInvalidation());
767 } else if (!mDownscaler && top != mInfo.output_scanline) {
768 PostInvalidation(nsIntRect(0, top,
769 mInfo.output_width,
770 mInfo.output_scanline - top));
771 }
772 }
773
774 // Override the standard error method in the IJG JPEG decoder code.
775 METHODDEF(void)
776 my_error_exit (j_common_ptr cinfo)
777 {
778 decoder_error_mgr* err = (decoder_error_mgr*) cinfo->err;
779
780 // Convert error to a browser error code
781 nsresult error_code = err->pub.msg_code == JERR_OUT_OF_MEMORY
782 ? NS_ERROR_OUT_OF_MEMORY
783 : NS_ERROR_FAILURE;
784
785 #ifdef DEBUG
786 char buffer[JMSG_LENGTH_MAX];
787
788 // Create the message
789 (*err->pub.format_message) (cinfo, buffer);
790
791 fprintf(stderr, "JPEG decoding error:\n%s\n", buffer);
792 #endif
793
794 // Return control to the setjmp point. We pass an nsresult masquerading as
795 // an int, which works because the setjmp() caller casts it back.
796 longjmp(err->setjmp_buffer, static_cast<int>(error_code));
797 }
798
799 /*******************************************************************************
800 * This is the callback routine from the IJG JPEG library used to supply new
801 * data to the decompressor when its input buffer is exhausted. It juggles
802 * multiple buffers in an attempt to avoid unnecessary copying of input data.
803 *
804 * (A simpler scheme is possible: It's much easier to use only a single
805 * buffer; when fill_input_buffer() is called, move any unconsumed data
806 * (beyond the current pointer/count) down to the beginning of this buffer and
807 * then load new data into the remaining buffer space. This approach requires
808 * a little more data copying but is far easier to get right.)
809 *
810 * At any one time, the JPEG decompressor is either reading from the necko
811 * input buffer, which is volatile across top-level calls to the IJG library,
812 * or the "backtrack" buffer. The backtrack buffer contains the remaining
813 * unconsumed data from the necko buffer after parsing was suspended due
814 * to insufficient data in some previous call to the IJG library.
815 *
816 * When suspending, the decompressor will back up to a convenient restart
817 * point (typically the start of the current MCU). The variables
818 * next_input_byte & bytes_in_buffer indicate where the restart point will be
819 * if the current call returns FALSE. Data beyond this point must be
820 * rescanned after resumption, so it must be preserved in case the decompressor
821 * decides to backtrack.
822 *
823 * Returns:
824 * TRUE if additional data is available, FALSE if no data present and
825 * the JPEG library should therefore suspend processing of input stream
826 ******************************************************************************/
827
828 /******************************************************************************/
829 /* data source manager method */
830 /******************************************************************************/
831
832 /******************************************************************************/
833 /* data source manager method
834 Initialize source. This is called by jpeg_read_header() before any
835 data is actually read. May leave
836 bytes_in_buffer set to 0 (in which case a fill_input_buffer() call
837 will occur immediately).
838 */
839 METHODDEF(void)
840 init_source (j_decompress_ptr jd)
841 {
842 }
843
844 /******************************************************************************/
845 /* data source manager method
846 Skip num_bytes worth of data. The buffer pointer and count should
847 be advanced over num_bytes input bytes, refilling the buffer as
848 needed. This is used to skip over a potentially large amount of
849 uninteresting data (such as an APPn marker). In some applications
850 it may be possible to optimize away the reading of the skipped data,
851 but it's not clear that being smart is worth much trouble; large
852 skips are uncommon. bytes_in_buffer may be zero on return.
853 A zero or negative skip count should be treated as a no-op.
854 */
855 METHODDEF(void)
856 skip_input_data (j_decompress_ptr jd, long num_bytes)
857 {
858 struct jpeg_source_mgr* src = jd->src;
859 nsJPEGDecoder* decoder = (nsJPEGDecoder*)(jd->client_data);
860
861 if (num_bytes > (long)src->bytes_in_buffer) {
862 // Can't skip it all right now until we get more data from
863 // network stream. Set things up so that fill_input_buffer
864 // will skip remaining amount.
865 decoder->mBytesToSkip = (size_t)num_bytes - src->bytes_in_buffer;
866 src->next_input_byte += src->bytes_in_buffer;
867 src->bytes_in_buffer = 0;
868
869 } else {
870 // Simple case. Just advance buffer pointer
871
872 src->bytes_in_buffer -= (size_t)num_bytes;
873 src->next_input_byte += num_bytes;
874 }
875 }
876
877 /******************************************************************************/
878 /* data source manager method
879 This is called whenever bytes_in_buffer has reached zero and more
880 data is wanted. In typical applications, it should read fresh data
881 into the buffer (ignoring the current state of next_input_byte and
882 bytes_in_buffer), reset the pointer & count to the start of the
883 buffer, and return TRUE indicating that the buffer has been reloaded.
884 It is not necessary to fill the buffer entirely, only to obtain at
885 least one more byte. bytes_in_buffer MUST be set to a positive value
886 if TRUE is returned. A FALSE return should only be used when I/O
887 suspension is desired.
888 */
889 METHODDEF(boolean)
890 fill_input_buffer (j_decompress_ptr jd)
891 {
892 struct jpeg_source_mgr* src = jd->src;
893 nsJPEGDecoder* decoder = (nsJPEGDecoder*)(jd->client_data);
894
895 if (decoder->mReading) {
896 const JOCTET* new_buffer = decoder->mSegment;
897 uint32_t new_buflen = decoder->mSegmentLen;
898
899 if (!new_buffer || new_buflen == 0) {
900 return false; // suspend
901 }
902
903 decoder->mSegmentLen = 0;
904
905 if (decoder->mBytesToSkip) {
906 if (decoder->mBytesToSkip < new_buflen) {
907 // All done skipping bytes; Return what's left.
908 new_buffer += decoder->mBytesToSkip;
909 new_buflen -= decoder->mBytesToSkip;
910 decoder->mBytesToSkip = 0;
911 } else {
912 // Still need to skip some more data in the future
913 decoder->mBytesToSkip -= (size_t)new_buflen;
914 return false; // suspend
915 }
916 }
917
918 decoder->mBackBufferUnreadLen = src->bytes_in_buffer;
919
920 src->next_input_byte = new_buffer;
921 src->bytes_in_buffer = (size_t)new_buflen;
922 decoder->mReading = false;
923
924 return true;
925 }
926
927 if (src->next_input_byte != decoder->mSegment) {
928 // Backtrack data has been permanently consumed.
929 decoder->mBackBufferUnreadLen = 0;
930 decoder->mBackBufferLen = 0;
931 }
932
933 // Save remainder of netlib buffer in backtrack buffer
934 const uint32_t new_backtrack_buflen = src->bytes_in_buffer +
935 decoder->mBackBufferLen;
936
937 // Make sure backtrack buffer is big enough to hold new data.
938 if (decoder->mBackBufferSize < new_backtrack_buflen) {
939 // Check for malformed MARKER segment lengths, before allocating space
940 // for it
941 if (new_backtrack_buflen > MAX_JPEG_MARKER_LENGTH) {
942 my_error_exit((j_common_ptr)(&decoder->mInfo));
943 }
944
945 // Round up to multiple of 256 bytes.
946 const size_t roundup_buflen = ((new_backtrack_buflen + 255) >> 8) << 8;
947 JOCTET* buf = (JOCTET*)PR_REALLOC(decoder->mBackBuffer, roundup_buflen);
948 // Check for OOM
949 if (!buf) {
950 decoder->mInfo.err->msg_code = JERR_OUT_OF_MEMORY;
951 my_error_exit((j_common_ptr)(&decoder->mInfo));
952 }
953 decoder->mBackBuffer = buf;
954 decoder->mBackBufferSize = roundup_buflen;
955 }
956
957 // Copy remainder of netlib segment into backtrack buffer.
958 memmove(decoder->mBackBuffer + decoder->mBackBufferLen,
959 src->next_input_byte,
960 src->bytes_in_buffer);
961
962 // Point to start of data to be rescanned.
963 src->next_input_byte = decoder->mBackBuffer + decoder->mBackBufferLen -
964 decoder->mBackBufferUnreadLen;
965 src->bytes_in_buffer += decoder->mBackBufferUnreadLen;
966 decoder->mBackBufferLen = (size_t)new_backtrack_buflen;
967 decoder->mReading = true;
968
969 return false;
970 }
971
972 /******************************************************************************/
973 /* data source manager method */
974 /*
975 * Terminate source --- called by jpeg_finish_decompress() after all
976 * data has been read to clean up JPEG source manager. NOT called by
977 * jpeg_abort() or jpeg_destroy().
978 */
979 METHODDEF(void)
980 term_source (j_decompress_ptr jd)
981 {
982 nsJPEGDecoder* decoder = (nsJPEGDecoder*)(jd->client_data);
983
984 // This function shouldn't be called if we ran into an error we didn't
985 // recover from.
986 MOZ_ASSERT(decoder->mState != JPEG_ERROR,
987 "Calling term_source on a JPEG with mState == JPEG_ERROR!");
988
989 // Notify using a helper method to get around protectedness issues.
990 decoder->NotifyDone();
991 }
992
993 } // namespace image
994 } // namespace mozilla
995
996 #ifndef JCS_EXTENSIONS
997 /**************** YCbCr -> Cairo's RGB24/ARGB32 conversion: most common case **************/
998
999 /*
1000 * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
1001 * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
1002 * The conversion equations to be implemented are therefore
1003 * R = Y + 1.40200 * Cr
1004 * G = Y - 0.34414 * Cb - 0.71414 * Cr
1005 * B = Y + 1.77200 * Cb
1006 * where Cb and Cr represent the incoming values less CENTERJSAMPLE.
1007 * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
1008 *
1009 * To avoid floating-point arithmetic, we represent the fractional constants
1010 * as integers scaled up by 2^16 (about 4 digits precision); we have to divide
1011 * the products by 2^16, with appropriate rounding, to get the correct answer.
1012 * Notice that Y, being an integral input, does not contribute any fraction
1013 * so it need not participate in the rounding.
1014 *
1015 * For even more speed, we avoid doing any multiplications in the inner loop
1016 * by precalculating the constants times Cb and Cr for all possible values.
1017 * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
1018 * for 12-bit samples it is still acceptable. It's not very reasonable for
1019 * 16-bit samples, but if you want lossless storage you shouldn't be changing
1020 * colorspace anyway.
1021 * The Cr=>R and Cb=>B values can be rounded to integers in advance; the
1022 * values for the G calculation are left scaled up, since we must add them
1023 * together before rounding.
1024 */
1025
1026 #define SCALEBITS 16 /* speediest right-shift on some machines */
1027
1028 /* Use static tables for color processing. */
1029 /* Four tables, each 256 entries of 4 bytes totals 4K which is not bad... */
1030
1031 const int Cr_r_tab[(MAXJSAMPLE+1) * sizeof(int)] ={
1032 -0xb3, -0xb2, -0xb1, -0xaf, -0xae, -0xac,
1033 -0xab, -0xaa, -0xa8, -0xa7, -0xa5, -0xa4,
1034 -0xa3, -0xa1, -0xa0, -0x9e, -0x9d, -0x9c,
1035 -0x9a, -0x99, -0x97, -0x96, -0x95, -0x93,
1036 -0x92, -0x90, -0x8f, -0x8e, -0x8c, -0x8b,
1037 -0x89, -0x88, -0x87, -0x85, -0x84, -0x82,
1038 -0x81, -0x80, -0x7e, -0x7d, -0x7b, -0x7a,
1039 -0x79, -0x77, -0x76, -0x74, -0x73, -0x72,
1040 -0x70, -0x6f, -0x6d, -0x6c, -0x6b, -0x69,
1041 -0x68, -0x66, -0x65, -0x64, -0x62, -0x61,
1042 -0x5f, -0x5e, -0x5d, -0x5b, -0x5a, -0x58,
1043 -0x57, -0x56, -0x54, -0x53, -0x51, -0x50,
1044 -0x4f, -0x4d, -0x4c, -0x4a, -0x49, -0x48,
1045 -0x46, -0x45, -0x43, -0x42, -0x40, -0x3f,
1046 -0x3e, -0x3c, -0x3b, -0x39, -0x38, -0x37,
1047 -0x35, -0x34, -0x32, -0x31, -0x30, -0x2e,
1048 -0x2d, -0x2b, -0x2a, -0x29, -0x27, -0x26,
1049 -0x24, -0x23, -0x22, -0x20, -0x1f, -0x1d,
1050 -0x1c, -0x1b, -0x19, -0x18, -0x16, -0x15,
1051 -0x14, -0x12, -0x11, -0x0f, -0x0e, -0x0d,
1052 -0x0b, -0x0a, -0x08, -0x07, -0x06, -0x04,
1053 -0x03, -0x01, 0x00, 0x01, 0x03, 0x04,
1054 0x06, 0x07, 0x08, 0x0a, 0x0b, 0x0d,
1055 0x0e, 0x0f, 0x11, 0x12, 0x14, 0x15,
1056 0x16, 0x18, 0x19, 0x1b, 0x1c, 0x1d,
1057 0x1f, 0x20, 0x22, 0x23, 0x24, 0x26,
1058 0x27, 0x29, 0x2a, 0x2b, 0x2d, 0x2e,
1059 0x30, 0x31, 0x32, 0x34, 0x35, 0x37,
1060 0x38, 0x39, 0x3b, 0x3c, 0x3e, 0x3f,
1061 0x40, 0x42, 0x43, 0x45, 0x46, 0x48,
1062 0x49, 0x4a, 0x4c, 0x4d, 0x4f, 0x50,
1063 0x51, 0x53, 0x54, 0x56, 0x57, 0x58,
1064 0x5a, 0x5b, 0x5d, 0x5e, 0x5f, 0x61,
1065 0x62, 0x64, 0x65, 0x66, 0x68, 0x69,
1066 0x6b, 0x6c, 0x6d, 0x6f, 0x70, 0x72,
1067 0x73, 0x74, 0x76, 0x77, 0x79, 0x7a,
1068 0x7b, 0x7d, 0x7e, 0x80, 0x81, 0x82,
1069 0x84, 0x85, 0x87, 0x88, 0x89, 0x8b,
1070 0x8c, 0x8e, 0x8f, 0x90, 0x92, 0x93,
1071 0x95, 0x96, 0x97, 0x99, 0x9a, 0x9c,
1072 0x9d, 0x9e, 0xa0, 0xa1, 0xa3, 0xa4,
1073 0xa5, 0xa7, 0xa8, 0xaa, 0xab, 0xac,
1074 0xae, 0xaf, 0xb1, 0xb2,
1075 };
1076
1077 const int Cb_b_tab[(MAXJSAMPLE+1) * sizeof(int)] ={
1078 -0xe3, -0xe1, -0xdf, -0xde, -0xdc, -0xda,
1079 -0xd8, -0xd6, -0xd5, -0xd3, -0xd1, -0xcf,
1080 -0xce, -0xcc, -0xca, -0xc8, -0xc6, -0xc5,
1081 -0xc3, -0xc1, -0xbf, -0xbe, -0xbc, -0xba,
1082 -0xb8, -0xb7, -0xb5, -0xb3, -0xb1, -0xaf,
1083 -0xae, -0xac, -0xaa, -0xa8, -0xa7, -0xa5,
1084 -0xa3, -0xa1, -0x9f, -0x9e, -0x9c, -0x9a,
1085 -0x98, -0x97, -0x95, -0x93, -0x91, -0x90,
1086 -0x8e, -0x8c, -0x8a, -0x88, -0x87, -0x85,
1087 -0x83, -0x81, -0x80, -0x7e, -0x7c, -0x7a,
1088 -0x78, -0x77, -0x75, -0x73, -0x71, -0x70,
1089 -0x6e, -0x6c, -0x6a, -0x69, -0x67, -0x65,
1090 -0x63, -0x61, -0x60, -0x5e, -0x5c, -0x5a,
1091 -0x59, -0x57, -0x55, -0x53, -0x52, -0x50,
1092 -0x4e, -0x4c, -0x4a, -0x49, -0x47, -0x45,
1093 -0x43, -0x42, -0x40, -0x3e, -0x3c, -0x3a,
1094 -0x39, -0x37, -0x35, -0x33, -0x32, -0x30,
1095 -0x2e, -0x2c, -0x2b, -0x29, -0x27, -0x25,
1096 -0x23, -0x22, -0x20, -0x1e, -0x1c, -0x1b,
1097 -0x19, -0x17, -0x15, -0x13, -0x12, -0x10,
1098 -0x0e, -0x0c, -0x0b, -0x09, -0x07, -0x05,
1099 -0x04, -0x02, 0x00, 0x02, 0x04, 0x05,
1100 0x07, 0x09, 0x0b, 0x0c, 0x0e, 0x10,
1101 0x12, 0x13, 0x15, 0x17, 0x19, 0x1b,
1102 0x1c, 0x1e, 0x20, 0x22, 0x23, 0x25,
1103 0x27, 0x29, 0x2b, 0x2c, 0x2e, 0x30,
1104 0x32, 0x33, 0x35, 0x37, 0x39, 0x3a,
1105 0x3c, 0x3e, 0x40, 0x42, 0x43, 0x45,
1106 0x47, 0x49, 0x4a, 0x4c, 0x4e, 0x50,
1107 0x52, 0x53, 0x55, 0x57, 0x59, 0x5a,
1108 0x5c, 0x5e, 0x60, 0x61, 0x63, 0x65,
1109 0x67, 0x69, 0x6a, 0x6c, 0x6e, 0x70,
1110 0x71, 0x73, 0x75, 0x77, 0x78, 0x7a,
1111 0x7c, 0x7e, 0x80, 0x81, 0x83, 0x85,
1112 0x87, 0x88, 0x8a, 0x8c, 0x8e, 0x90,
1113 0x91, 0x93, 0x95, 0x97, 0x98, 0x9a,
1114 0x9c, 0x9e, 0x9f, 0xa1, 0xa3, 0xa5,
1115 0xa7, 0xa8, 0xaa, 0xac, 0xae, 0xaf,
1116 0xb1, 0xb3, 0xb5, 0xb7, 0xb8, 0xba,
1117 0xbc, 0xbe, 0xbf, 0xc1, 0xc3, 0xc5,
1118 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xcf,
1119 0xd1, 0xd3, 0xd5, 0xd6, 0xd8, 0xda,
1120 0xdc, 0xde, 0xdf, 0xe1,
1121 };
1122
1123 const int Cr_g_tab[(MAXJSAMPLE+1) * sizeof(int)] ={
1124 0x5b6900, 0x5ab22e, 0x59fb5c, 0x59448a, 0x588db8, 0x57d6e6,
1125 0x572014, 0x566942, 0x55b270, 0x54fb9e, 0x5444cc, 0x538dfa,
1126 0x52d728, 0x522056, 0x516984, 0x50b2b2, 0x4ffbe0, 0x4f450e,
1127 0x4e8e3c, 0x4dd76a, 0x4d2098, 0x4c69c6, 0x4bb2f4, 0x4afc22,
1128 0x4a4550, 0x498e7e, 0x48d7ac, 0x4820da, 0x476a08, 0x46b336,
1129 0x45fc64, 0x454592, 0x448ec0, 0x43d7ee, 0x43211c, 0x426a4a,
1130 0x41b378, 0x40fca6, 0x4045d4, 0x3f8f02, 0x3ed830, 0x3e215e,
1131 0x3d6a8c, 0x3cb3ba, 0x3bfce8, 0x3b4616, 0x3a8f44, 0x39d872,
1132 0x3921a0, 0x386ace, 0x37b3fc, 0x36fd2a, 0x364658, 0x358f86,
1133 0x34d8b4, 0x3421e2, 0x336b10, 0x32b43e, 0x31fd6c, 0x31469a,
1134 0x308fc8, 0x2fd8f6, 0x2f2224, 0x2e6b52, 0x2db480, 0x2cfdae,
1135 0x2c46dc, 0x2b900a, 0x2ad938, 0x2a2266, 0x296b94, 0x28b4c2,
1136 0x27fdf0, 0x27471e, 0x26904c, 0x25d97a, 0x2522a8, 0x246bd6,
1137 0x23b504, 0x22fe32, 0x224760, 0x21908e, 0x20d9bc, 0x2022ea,
1138 0x1f6c18, 0x1eb546, 0x1dfe74, 0x1d47a2, 0x1c90d0, 0x1bd9fe,
1139 0x1b232c, 0x1a6c5a, 0x19b588, 0x18feb6, 0x1847e4, 0x179112,
1140 0x16da40, 0x16236e, 0x156c9c, 0x14b5ca, 0x13fef8, 0x134826,
1141 0x129154, 0x11da82, 0x1123b0, 0x106cde, 0x0fb60c, 0x0eff3a,
1142 0x0e4868, 0x0d9196, 0x0cdac4, 0x0c23f2, 0x0b6d20, 0x0ab64e,
1143 0x09ff7c, 0x0948aa, 0x0891d8, 0x07db06, 0x072434, 0x066d62,
1144 0x05b690, 0x04ffbe, 0x0448ec, 0x03921a, 0x02db48, 0x022476,
1145 0x016da4, 0x00b6d2, 0x000000, -0x00b6d2, -0x016da4, -0x022476,
1146 -0x02db48, -0x03921a, -0x0448ec, -0x04ffbe, -0x05b690, -0x066d62,
1147 -0x072434, -0x07db06, -0x0891d8, -0x0948aa, -0x09ff7c, -0x0ab64e,
1148 -0x0b6d20, -0x0c23f2, -0x0cdac4, -0x0d9196, -0x0e4868, -0x0eff3a,
1149 -0x0fb60c, -0x106cde, -0x1123b0, -0x11da82, -0x129154, -0x134826,
1150 -0x13fef8, -0x14b5ca, -0x156c9c, -0x16236e, -0x16da40, -0x179112,
1151 -0x1847e4, -0x18feb6, -0x19b588, -0x1a6c5a, -0x1b232c, -0x1bd9fe,
1152 -0x1c90d0, -0x1d47a2, -0x1dfe74, -0x1eb546, -0x1f6c18, -0x2022ea,
1153 -0x20d9bc, -0x21908e, -0x224760, -0x22fe32, -0x23b504, -0x246bd6,
1154 -0x2522a8, -0x25d97a, -0x26904c, -0x27471e, -0x27fdf0, -0x28b4c2,
1155 -0x296b94, -0x2a2266, -0x2ad938, -0x2b900a, -0x2c46dc, -0x2cfdae,
1156 -0x2db480, -0x2e6b52, -0x2f2224, -0x2fd8f6, -0x308fc8, -0x31469a,
1157 -0x31fd6c, -0x32b43e, -0x336b10, -0x3421e2, -0x34d8b4, -0x358f86,
1158 -0x364658, -0x36fd2a, -0x37b3fc, -0x386ace, -0x3921a0, -0x39d872,
1159 -0x3a8f44, -0x3b4616, -0x3bfce8, -0x3cb3ba, -0x3d6a8c, -0x3e215e,
1160 -0x3ed830, -0x3f8f02, -0x4045d4, -0x40fca6, -0x41b378, -0x426a4a,
1161 -0x43211c, -0x43d7ee, -0x448ec0, -0x454592, -0x45fc64, -0x46b336,
1162 -0x476a08, -0x4820da, -0x48d7ac, -0x498e7e, -0x4a4550, -0x4afc22,
1163 -0x4bb2f4, -0x4c69c6, -0x4d2098, -0x4dd76a, -0x4e8e3c, -0x4f450e,
1164 -0x4ffbe0, -0x50b2b2, -0x516984, -0x522056, -0x52d728, -0x538dfa,
1165 -0x5444cc, -0x54fb9e, -0x55b270, -0x566942, -0x572014, -0x57d6e6,
1166 -0x588db8, -0x59448a, -0x59fb5c, -0x5ab22e,
1167 };
1168
1169 const int Cb_g_tab[(MAXJSAMPLE+1) * sizeof(int)] ={
1170 0x2c8d00, 0x2c34e6, 0x2bdccc, 0x2b84b2, 0x2b2c98, 0x2ad47e,
1171 0x2a7c64, 0x2a244a, 0x29cc30, 0x297416, 0x291bfc, 0x28c3e2,
1172 0x286bc8, 0x2813ae, 0x27bb94, 0x27637a, 0x270b60, 0x26b346,
1173 0x265b2c, 0x260312, 0x25aaf8, 0x2552de, 0x24fac4, 0x24a2aa,
1174 0x244a90, 0x23f276, 0x239a5c, 0x234242, 0x22ea28, 0x22920e,
1175 0x2239f4, 0x21e1da, 0x2189c0, 0x2131a6, 0x20d98c, 0x208172,
1176 0x202958, 0x1fd13e, 0x1f7924, 0x1f210a, 0x1ec8f0, 0x1e70d6,
1177 0x1e18bc, 0x1dc0a2, 0x1d6888, 0x1d106e, 0x1cb854, 0x1c603a,
1178 0x1c0820, 0x1bb006, 0x1b57ec, 0x1affd2, 0x1aa7b8, 0x1a4f9e,
1179 0x19f784, 0x199f6a, 0x194750, 0x18ef36, 0x18971c, 0x183f02,
1180 0x17e6e8, 0x178ece, 0x1736b4, 0x16de9a, 0x168680, 0x162e66,
1181 0x15d64c, 0x157e32, 0x152618, 0x14cdfe, 0x1475e4, 0x141dca,
1182 0x13c5b0, 0x136d96, 0x13157c, 0x12bd62, 0x126548, 0x120d2e,
1183 0x11b514, 0x115cfa, 0x1104e0, 0x10acc6, 0x1054ac, 0x0ffc92,
1184 0x0fa478, 0x0f4c5e, 0x0ef444, 0x0e9c2a, 0x0e4410, 0x0debf6,
1185 0x0d93dc, 0x0d3bc2, 0x0ce3a8, 0x0c8b8e, 0x0c3374, 0x0bdb5a,
1186 0x0b8340, 0x0b2b26, 0x0ad30c, 0x0a7af2, 0x0a22d8, 0x09cabe,
1187 0x0972a4, 0x091a8a, 0x08c270, 0x086a56, 0x08123c, 0x07ba22,
1188 0x076208, 0x0709ee, 0x06b1d4, 0x0659ba, 0x0601a0, 0x05a986,
1189 0x05516c, 0x04f952, 0x04a138, 0x04491e, 0x03f104, 0x0398ea,
1190 0x0340d0, 0x02e8b6, 0x02909c, 0x023882, 0x01e068, 0x01884e,
1191 0x013034, 0x00d81a, 0x008000, 0x0027e6, -0x003034, -0x00884e,
1192 -0x00e068, -0x013882, -0x01909c, -0x01e8b6, -0x0240d0, -0x0298ea,
1193 -0x02f104, -0x03491e, -0x03a138, -0x03f952, -0x04516c, -0x04a986,
1194 -0x0501a0, -0x0559ba, -0x05b1d4, -0x0609ee, -0x066208, -0x06ba22,
1195 -0x07123c, -0x076a56, -0x07c270, -0x081a8a, -0x0872a4, -0x08cabe,
1196 -0x0922d8, -0x097af2, -0x09d30c, -0x0a2b26, -0x0a8340, -0x0adb5a,
1197 -0x0b3374, -0x0b8b8e, -0x0be3a8, -0x0c3bc2, -0x0c93dc, -0x0cebf6,
1198 -0x0d4410, -0x0d9c2a, -0x0df444, -0x0e4c5e, -0x0ea478, -0x0efc92,
1199 -0x0f54ac, -0x0facc6, -0x1004e0, -0x105cfa, -0x10b514, -0x110d2e,
1200 -0x116548, -0x11bd62, -0x12157c, -0x126d96, -0x12c5b0, -0x131dca,
1201 -0x1375e4, -0x13cdfe, -0x142618, -0x147e32, -0x14d64c, -0x152e66,
1202 -0x158680, -0x15de9a, -0x1636b4, -0x168ece, -0x16e6e8, -0x173f02,
1203 -0x17971c, -0x17ef36, -0x184750, -0x189f6a, -0x18f784, -0x194f9e,
1204 -0x19a7b8, -0x19ffd2, -0x1a57ec, -0x1ab006, -0x1b0820, -0x1b603a,
1205 -0x1bb854, -0x1c106e, -0x1c6888, -0x1cc0a2, -0x1d18bc, -0x1d70d6,
1206 -0x1dc8f0, -0x1e210a, -0x1e7924, -0x1ed13e, -0x1f2958, -0x1f8172,
1207 -0x1fd98c, -0x2031a6, -0x2089c0, -0x20e1da, -0x2139f4, -0x21920e,
1208 -0x21ea28, -0x224242, -0x229a5c, -0x22f276, -0x234a90, -0x23a2aa,
1209 -0x23fac4, -0x2452de, -0x24aaf8, -0x250312, -0x255b2c, -0x25b346,
1210 -0x260b60, -0x26637a, -0x26bb94, -0x2713ae, -0x276bc8, -0x27c3e2,
1211 -0x281bfc, -0x287416, -0x28cc30, -0x29244a, -0x297c64, -0x29d47e,
1212 -0x2a2c98, -0x2a84b2, -0x2adccc, -0x2b34e6,
1213 };
1214
1215
1216 /* We assume that right shift corresponds to signed division by 2 with
1217 * rounding towards minus infinity. This is correct for typical "arithmetic
1218 * shift" instructions that shift in copies of the sign bit. But some
1219 * C compilers implement >> with an unsigned shift. For these machines you
1220 * must define RIGHT_SHIFT_IS_UNSIGNED.
1221 * RIGHT_SHIFT provides a proper signed right shift of an INT32 quantity.
1222 * It is only applied with constant shift counts. SHIFT_TEMPS must be
1223 * included in the variables of any routine using RIGHT_SHIFT.
1224 */
1225
1226 #ifdef RIGHT_SHIFT_IS_UNSIGNED
1227 #define SHIFT_TEMPS INT32 shift_temp;
1228 #define RIGHT_SHIFT(x,shft) \
1229 ((shift_temp = (x)) < 0 ? \
1230 (shift_temp >> (shft)) | ((~((INT32) 0)) << (32-(shft))) : \
1231 (shift_temp >> (shft)))
1232 #else
1233 #define SHIFT_TEMPS
1234 #define RIGHT_SHIFT(x,shft) ((x) >> (shft))
1235 #endif
1236
1237
1238 METHODDEF(void)
ycc_rgb_convert_argb(j_decompress_ptr cinfo,JSAMPIMAGE input_buf,JDIMENSION input_row,JSAMPARRAY output_buf,int num_rows)1239 ycc_rgb_convert_argb (j_decompress_ptr cinfo,
1240 JSAMPIMAGE input_buf, JDIMENSION input_row,
1241 JSAMPARRAY output_buf, int num_rows)
1242 {
1243 JDIMENSION num_cols = cinfo->output_width;
1244 JSAMPLE * range_limit = cinfo->sample_range_limit;
1245
1246 SHIFT_TEMPS
1247
1248 /* This is used if we don't have SSE2 */
1249
1250 while (--num_rows >= 0) {
1251 JSAMPROW inptr0 = input_buf[0][input_row];
1252 JSAMPROW inptr1 = input_buf[1][input_row];
1253 JSAMPROW inptr2 = input_buf[2][input_row];
1254 input_row++;
1255 uint32_t *outptr = (uint32_t *) *output_buf++;
1256 for (JDIMENSION col = 0; col < num_cols; col++) {
1257 int y = GETJSAMPLE(inptr0[col]);
1258 int cb = GETJSAMPLE(inptr1[col]);
1259 int cr = GETJSAMPLE(inptr2[col]);
1260 JSAMPLE * range_limit_y = range_limit + y;
1261 /* Range-limiting is essential due to noise introduced by DCT losses. */
1262 outptr[col] = 0xFF000000 |
1263 ( range_limit_y[Cr_r_tab[cr]] << 16 ) |
1264 ( range_limit_y[((int) RIGHT_SHIFT(Cb_g_tab[cb] + Cr_g_tab[cr], SCALEBITS))] << 8 ) |
1265 ( range_limit_y[Cb_b_tab[cb]] );
1266 }
1267 }
1268 }
1269 #endif
1270
1271
1272 ///*************** Inverted CMYK -> RGB conversion *************************
1273 /// Input is (Inverted) CMYK stored as 4 bytes per pixel.
1274 /// Output is RGB stored as 3 bytes per pixel.
1275 /// @param row Points to row buffer containing the CMYK bytes for each pixel
1276 /// in the row.
1277 /// @param width Number of pixels in the row.
cmyk_convert_rgb(JSAMPROW row,JDIMENSION width)1278 static void cmyk_convert_rgb(JSAMPROW row, JDIMENSION width)
1279 {
1280 // Work from end to front to shrink from 4 bytes per pixel to 3
1281 JSAMPROW in = row + width*4;
1282 JSAMPROW out = in;
1283
1284 for (uint32_t i = width; i > 0; i--) {
1285 in -= 4;
1286 out -= 3;
1287
1288 // Source is 'Inverted CMYK', output is RGB.
1289 // See: http://www.easyrgb.com/math.php?MATH=M12#text12
1290 // Or: http://www.ilkeratalay.com/colorspacesfaq.php#rgb
1291
1292 // From CMYK to CMY
1293 // C = ( C * ( 1 - K ) + K )
1294 // M = ( M * ( 1 - K ) + K )
1295 // Y = ( Y * ( 1 - K ) + K )
1296
1297 // From Inverted CMYK to CMY is thus:
1298 // C = ( (1-iC) * (1 - (1-iK)) + (1-iK) ) => 1 - iC*iK
1299 // Same for M and Y
1300
1301 // Convert from CMY (0..1) to RGB (0..1)
1302 // R = 1 - C => 1 - (1 - iC*iK) => iC*iK
1303 // G = 1 - M => 1 - (1 - iM*iK) => iM*iK
1304 // B = 1 - Y => 1 - (1 - iY*iK) => iY*iK
1305
1306 // Convert from Inverted CMYK (0..255) to RGB (0..255)
1307 const uint32_t iC = in[0];
1308 const uint32_t iM = in[1];
1309 const uint32_t iY = in[2];
1310 const uint32_t iK = in[3];
1311 out[0] = iC*iK/255; // Red
1312 out[1] = iM*iK/255; // Green
1313 out[2] = iY*iK/255; // Blue
1314 }
1315 }
1316