summaryrefslogtreecommitdiff
path: root/www/firefox/patches/patch-image_decoders_nsJPEGDecoder.cpp
blob: c61ec8318a229bce2d596fe35bf098e6771a6f9e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
$NetBSD: patch-image_decoders_nsJPEGDecoder.cpp,v 1.8 2016/12/03 09:58:26 ryoon Exp $

Partially revert https://bugzilla.mozilla.org/show_bug.cgi?id=791305
to allow building against jpeg (not jpeg-turbo).

--- image/decoders/nsJPEGDecoder.cpp.orig	2016-10-31 20:15:32.000000000 +0000
+++ image/decoders/nsJPEGDecoder.cpp
@@ -28,13 +28,28 @@
 
 extern "C" {
 #include "iccjpeg.h"
-}
 
+#ifdef JCS_EXTENSIONS
 #if MOZ_BIG_ENDIAN
 #define MOZ_JCS_EXT_NATIVE_ENDIAN_XRGB JCS_EXT_XRGB
 #else
 #define MOZ_JCS_EXT_NATIVE_ENDIAN_XRGB JCS_EXT_BGRX
 #endif
+#else
+/* Colorspace conversion (copied from jpegint.h) */
+struct jpeg_color_deconverter {
+  JMETHOD(void, start_pass, (j_decompress_ptr cinfo));
+  JMETHOD(void, color_convert, (j_decompress_ptr cinfo,
+				JSAMPIMAGE input_buf, JDIMENSION input_row,
+				JSAMPARRAY output_buf, int num_rows));
+};
+
+METHODDEF(void)
+ycc_rgb_convert_argb (j_decompress_ptr cinfo,
+                 JSAMPIMAGE input_buf, JDIMENSION input_row,
+                 JSAMPARRAY output_buf, int num_rows);
+#endif
+}
 
 static void cmyk_convert_rgb(JSAMPROW row, JDIMENSION width);
 
@@ -360,6 +375,7 @@ nsJPEGDecoder::ReadJPEGData(const char* 
         case JCS_GRAYSCALE:
         case JCS_RGB:
         case JCS_YCbCr:
+#ifdef JCS_EXTENSIONS
           // if we're not color managing we can decode directly to
           // MOZ_JCS_EXT_NATIVE_ENDIAN_XRGB
           if (mCMSMode != eCMSMode_All) {
@@ -368,6 +384,9 @@ nsJPEGDecoder::ReadJPEGData(const char* 
           } else {
               mInfo.out_color_space = JCS_RGB;
           }
+#else
+          mInfo.out_color_space = JCS_RGB;
+#endif
           break;
         case JCS_CMYK:
         case JCS_YCCK:
@@ -441,6 +460,16 @@ nsJPEGDecoder::ReadJPEGData(const char* 
       return Transition::ContinueUnbuffered(State::JPEG_DATA); // I/O suspension
     }
 
+#ifndef JCS_EXTENSIONS
+    /* Force to use our YCbCr to Packed RGB converter when possible */
+    if (!mTransform && (mCMSMode != eCMSMode_All) &&
+        mInfo.jpeg_color_space == JCS_YCbCr && mInfo.out_color_space == JCS_RGB) {
+      /* Special case for the most common case: transform from YCbCr direct into packed ARGB */
+      mInfo.out_color_components = 4; /* Packed ARGB pixels are always 4 bytes...*/
+      mInfo.cconvert->color_convert = ycc_rgb_convert_argb;
+    }
+#endif
+
     // If this is a progressive JPEG ...
     mState = mInfo.buffered_image ?
              JPEG_DECOMPRESS_PROGRESSIVE : JPEG_DECOMPRESS_SEQUENTIAL;
@@ -638,7 +667,11 @@ nsJPEGDecoder::OutputScanlines(bool* sus
 
       MOZ_ASSERT(imageRow, "Should have a row buffer here");
 
+#ifdef JCS_EXTENSIONS
       if (mInfo.out_color_space == MOZ_JCS_EXT_NATIVE_ENDIAN_XRGB) {
+#else
+      if (mInfo.cconvert->color_convert == ycc_rgb_convert_argb) {
+#endif
         // Special case: scanline will be directly converted into packed ARGB
         if (jpeg_read_scanlines(&mInfo, (JSAMPARRAY)&imageRow, 1) != 1) {
           *suspend = true; // suspend
@@ -962,6 +995,282 @@ term_source (j_decompress_ptr jd)
 } // namespace image
 } // namespace mozilla
 
+#ifndef JCS_EXTENSIONS
+/**************** YCbCr -> Cairo's RGB24/ARGB32 conversion: most common case **************/
+
+/*
+ * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
+ * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
+ * The conversion equations to be implemented are therefore
+ *      R = Y                + 1.40200 * Cr
+ *      G = Y - 0.34414 * Cb - 0.71414 * Cr
+ *      B = Y + 1.77200 * Cb
+ * where Cb and Cr represent the incoming values less CENTERJSAMPLE.
+ * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
+ *
+ * To avoid floating-point arithmetic, we represent the fractional constants
+ * as integers scaled up by 2^16 (about 4 digits precision); we have to divide
+ * the products by 2^16, with appropriate rounding, to get the correct answer.
+ * Notice that Y, being an integral input, does not contribute any fraction
+ * so it need not participate in the rounding.
+ *
+ * For even more speed, we avoid doing any multiplications in the inner loop
+ * by precalculating the constants times Cb and Cr for all possible values.
+ * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
+ * for 12-bit samples it is still acceptable.  It's not very reasonable for
+ * 16-bit samples, but if you want lossless storage you shouldn't be changing
+ * colorspace anyway.
+ * The Cr=>R and Cb=>B values can be rounded to integers in advance; the
+ * values for the G calculation are left scaled up, since we must add them
+ * together before rounding.
+ */
+
+#define SCALEBITS       16      /* speediest right-shift on some machines */
+
+/* Use static tables for color processing. */
+/* Four tables, each 256 entries of 4 bytes totals 4K which is not bad... */
+
+const int Cr_r_tab[(MAXJSAMPLE+1) * sizeof(int)] ={
+       -0xb3,       -0xb2,       -0xb1,       -0xaf,       -0xae,       -0xac,
+       -0xab,       -0xaa,       -0xa8,       -0xa7,       -0xa5,       -0xa4,
+       -0xa3,       -0xa1,       -0xa0,       -0x9e,       -0x9d,       -0x9c,
+       -0x9a,       -0x99,       -0x97,       -0x96,       -0x95,       -0x93,
+       -0x92,       -0x90,       -0x8f,       -0x8e,       -0x8c,       -0x8b,
+       -0x89,       -0x88,       -0x87,       -0x85,       -0x84,       -0x82,
+       -0x81,       -0x80,       -0x7e,       -0x7d,       -0x7b,       -0x7a,
+       -0x79,       -0x77,       -0x76,       -0x74,       -0x73,       -0x72,
+       -0x70,       -0x6f,       -0x6d,       -0x6c,       -0x6b,       -0x69,
+       -0x68,       -0x66,       -0x65,       -0x64,       -0x62,       -0x61,
+       -0x5f,       -0x5e,       -0x5d,       -0x5b,       -0x5a,       -0x58,
+       -0x57,       -0x56,       -0x54,       -0x53,       -0x51,       -0x50,
+       -0x4f,       -0x4d,       -0x4c,       -0x4a,       -0x49,       -0x48,
+       -0x46,       -0x45,       -0x43,       -0x42,       -0x40,       -0x3f,
+       -0x3e,       -0x3c,       -0x3b,       -0x39,       -0x38,       -0x37,
+       -0x35,       -0x34,       -0x32,       -0x31,       -0x30,       -0x2e,
+       -0x2d,       -0x2b,       -0x2a,       -0x29,       -0x27,       -0x26,
+       -0x24,       -0x23,       -0x22,       -0x20,       -0x1f,       -0x1d,
+       -0x1c,       -0x1b,       -0x19,       -0x18,       -0x16,       -0x15,
+       -0x14,       -0x12,       -0x11,       -0x0f,       -0x0e,       -0x0d,
+       -0x0b,       -0x0a,       -0x08,       -0x07,       -0x06,       -0x04,
+       -0x03,       -0x01,        0x00,        0x01,        0x03,        0x04,
+        0x06,        0x07,        0x08,        0x0a,        0x0b,        0x0d,
+        0x0e,        0x0f,        0x11,        0x12,        0x14,        0x15,
+        0x16,        0x18,        0x19,        0x1b,        0x1c,        0x1d,
+        0x1f,        0x20,        0x22,        0x23,        0x24,        0x26,
+        0x27,        0x29,        0x2a,        0x2b,        0x2d,        0x2e,
+        0x30,        0x31,        0x32,        0x34,        0x35,        0x37,
+        0x38,        0x39,        0x3b,        0x3c,        0x3e,        0x3f,
+        0x40,        0x42,        0x43,        0x45,        0x46,        0x48,
+        0x49,        0x4a,        0x4c,        0x4d,        0x4f,        0x50,
+        0x51,        0x53,        0x54,        0x56,        0x57,        0x58,
+        0x5a,        0x5b,        0x5d,        0x5e,        0x5f,        0x61,
+        0x62,        0x64,        0x65,        0x66,        0x68,        0x69,
+        0x6b,        0x6c,        0x6d,        0x6f,        0x70,        0x72,
+        0x73,        0x74,        0x76,        0x77,        0x79,        0x7a,
+        0x7b,        0x7d,        0x7e,        0x80,        0x81,        0x82,
+        0x84,        0x85,        0x87,        0x88,        0x89,        0x8b,
+        0x8c,        0x8e,        0x8f,        0x90,        0x92,        0x93,
+        0x95,        0x96,        0x97,        0x99,        0x9a,        0x9c,
+        0x9d,        0x9e,        0xa0,        0xa1,        0xa3,        0xa4,
+        0xa5,        0xa7,        0xa8,        0xaa,        0xab,        0xac,
+        0xae,        0xaf,        0xb1,        0xb2,
+  };
+
+const int Cb_b_tab[(MAXJSAMPLE+1) * sizeof(int)] ={
+       -0xe3,       -0xe1,       -0xdf,       -0xde,       -0xdc,       -0xda,
+       -0xd8,       -0xd6,       -0xd5,       -0xd3,       -0xd1,       -0xcf,
+       -0xce,       -0xcc,       -0xca,       -0xc8,       -0xc6,       -0xc5,
+       -0xc3,       -0xc1,       -0xbf,       -0xbe,       -0xbc,       -0xba,
+       -0xb8,       -0xb7,       -0xb5,       -0xb3,       -0xb1,       -0xaf,
+       -0xae,       -0xac,       -0xaa,       -0xa8,       -0xa7,       -0xa5,
+       -0xa3,       -0xa1,       -0x9f,       -0x9e,       -0x9c,       -0x9a,
+       -0x98,       -0x97,       -0x95,       -0x93,       -0x91,       -0x90,
+       -0x8e,       -0x8c,       -0x8a,       -0x88,       -0x87,       -0x85,
+       -0x83,       -0x81,       -0x80,       -0x7e,       -0x7c,       -0x7a,
+       -0x78,       -0x77,       -0x75,       -0x73,       -0x71,       -0x70,
+       -0x6e,       -0x6c,       -0x6a,       -0x69,       -0x67,       -0x65,
+       -0x63,       -0x61,       -0x60,       -0x5e,       -0x5c,       -0x5a,
+       -0x59,       -0x57,       -0x55,       -0x53,       -0x52,       -0x50,
+       -0x4e,       -0x4c,       -0x4a,       -0x49,       -0x47,       -0x45,
+       -0x43,       -0x42,       -0x40,       -0x3e,       -0x3c,       -0x3a,
+       -0x39,       -0x37,       -0x35,       -0x33,       -0x32,       -0x30,
+       -0x2e,       -0x2c,       -0x2b,       -0x29,       -0x27,       -0x25,
+       -0x23,       -0x22,       -0x20,       -0x1e,       -0x1c,       -0x1b,
+       -0x19,       -0x17,       -0x15,       -0x13,       -0x12,       -0x10,
+       -0x0e,       -0x0c,       -0x0b,       -0x09,       -0x07,       -0x05,
+       -0x04,       -0x02,        0x00,        0x02,        0x04,        0x05,
+        0x07,        0x09,        0x0b,        0x0c,        0x0e,        0x10,
+        0x12,        0x13,        0x15,        0x17,        0x19,        0x1b,
+        0x1c,        0x1e,        0x20,        0x22,        0x23,        0x25,
+        0x27,        0x29,        0x2b,        0x2c,        0x2e,        0x30,
+        0x32,        0x33,        0x35,        0x37,        0x39,        0x3a,
+        0x3c,        0x3e,        0x40,        0x42,        0x43,        0x45,
+        0x47,        0x49,        0x4a,        0x4c,        0x4e,        0x50,
+        0x52,        0x53,        0x55,        0x57,        0x59,        0x5a,
+        0x5c,        0x5e,        0x60,        0x61,        0x63,        0x65,
+        0x67,        0x69,        0x6a,        0x6c,        0x6e,        0x70,
+        0x71,        0x73,        0x75,        0x77,        0x78,        0x7a,
+        0x7c,        0x7e,        0x80,        0x81,        0x83,        0x85,
+        0x87,        0x88,        0x8a,        0x8c,        0x8e,        0x90,
+        0x91,        0x93,        0x95,        0x97,        0x98,        0x9a,
+        0x9c,        0x9e,        0x9f,        0xa1,        0xa3,        0xa5,
+        0xa7,        0xa8,        0xaa,        0xac,        0xae,        0xaf,
+        0xb1,        0xb3,        0xb5,        0xb7,        0xb8,        0xba,
+        0xbc,        0xbe,        0xbf,        0xc1,        0xc3,        0xc5,
+        0xc6,        0xc8,        0xca,        0xcc,        0xce,        0xcf,
+        0xd1,        0xd3,        0xd5,        0xd6,        0xd8,        0xda,
+        0xdc,        0xde,        0xdf,        0xe1,
+  };
+
+const int Cr_g_tab[(MAXJSAMPLE+1) * sizeof(int)] ={
+    0x5b6900,    0x5ab22e,    0x59fb5c,    0x59448a,    0x588db8,    0x57d6e6,
+    0x572014,    0x566942,    0x55b270,    0x54fb9e,    0x5444cc,    0x538dfa,
+    0x52d728,    0x522056,    0x516984,    0x50b2b2,    0x4ffbe0,    0x4f450e,
+    0x4e8e3c,    0x4dd76a,    0x4d2098,    0x4c69c6,    0x4bb2f4,    0x4afc22,
+    0x4a4550,    0x498e7e,    0x48d7ac,    0x4820da,    0x476a08,    0x46b336,
+    0x45fc64,    0x454592,    0x448ec0,    0x43d7ee,    0x43211c,    0x426a4a,
+    0x41b378,    0x40fca6,    0x4045d4,    0x3f8f02,    0x3ed830,    0x3e215e,
+    0x3d6a8c,    0x3cb3ba,    0x3bfce8,    0x3b4616,    0x3a8f44,    0x39d872,
+    0x3921a0,    0x386ace,    0x37b3fc,    0x36fd2a,    0x364658,    0x358f86,
+    0x34d8b4,    0x3421e2,    0x336b10,    0x32b43e,    0x31fd6c,    0x31469a,
+    0x308fc8,    0x2fd8f6,    0x2f2224,    0x2e6b52,    0x2db480,    0x2cfdae,
+    0x2c46dc,    0x2b900a,    0x2ad938,    0x2a2266,    0x296b94,    0x28b4c2,
+    0x27fdf0,    0x27471e,    0x26904c,    0x25d97a,    0x2522a8,    0x246bd6,
+    0x23b504,    0x22fe32,    0x224760,    0x21908e,    0x20d9bc,    0x2022ea,
+    0x1f6c18,    0x1eb546,    0x1dfe74,    0x1d47a2,    0x1c90d0,    0x1bd9fe,
+    0x1b232c,    0x1a6c5a,    0x19b588,    0x18feb6,    0x1847e4,    0x179112,
+    0x16da40,    0x16236e,    0x156c9c,    0x14b5ca,    0x13fef8,    0x134826,
+    0x129154,    0x11da82,    0x1123b0,    0x106cde,    0x0fb60c,    0x0eff3a,
+    0x0e4868,    0x0d9196,    0x0cdac4,    0x0c23f2,    0x0b6d20,    0x0ab64e,
+    0x09ff7c,    0x0948aa,    0x0891d8,    0x07db06,    0x072434,    0x066d62,
+    0x05b690,    0x04ffbe,    0x0448ec,    0x03921a,    0x02db48,    0x022476,
+    0x016da4,    0x00b6d2,    0x000000,   -0x00b6d2,   -0x016da4,   -0x022476,
+   -0x02db48,   -0x03921a,   -0x0448ec,   -0x04ffbe,   -0x05b690,   -0x066d62,
+   -0x072434,   -0x07db06,   -0x0891d8,   -0x0948aa,   -0x09ff7c,   -0x0ab64e,
+   -0x0b6d20,   -0x0c23f2,   -0x0cdac4,   -0x0d9196,   -0x0e4868,   -0x0eff3a,
+   -0x0fb60c,   -0x106cde,   -0x1123b0,   -0x11da82,   -0x129154,   -0x134826,
+   -0x13fef8,   -0x14b5ca,   -0x156c9c,   -0x16236e,   -0x16da40,   -0x179112,
+   -0x1847e4,   -0x18feb6,   -0x19b588,   -0x1a6c5a,   -0x1b232c,   -0x1bd9fe,
+   -0x1c90d0,   -0x1d47a2,   -0x1dfe74,   -0x1eb546,   -0x1f6c18,   -0x2022ea,
+   -0x20d9bc,   -0x21908e,   -0x224760,   -0x22fe32,   -0x23b504,   -0x246bd6,
+   -0x2522a8,   -0x25d97a,   -0x26904c,   -0x27471e,   -0x27fdf0,   -0x28b4c2,
+   -0x296b94,   -0x2a2266,   -0x2ad938,   -0x2b900a,   -0x2c46dc,   -0x2cfdae,
+   -0x2db480,   -0x2e6b52,   -0x2f2224,   -0x2fd8f6,   -0x308fc8,   -0x31469a,
+   -0x31fd6c,   -0x32b43e,   -0x336b10,   -0x3421e2,   -0x34d8b4,   -0x358f86,
+   -0x364658,   -0x36fd2a,   -0x37b3fc,   -0x386ace,   -0x3921a0,   -0x39d872,
+   -0x3a8f44,   -0x3b4616,   -0x3bfce8,   -0x3cb3ba,   -0x3d6a8c,   -0x3e215e,
+   -0x3ed830,   -0x3f8f02,   -0x4045d4,   -0x40fca6,   -0x41b378,   -0x426a4a,
+   -0x43211c,   -0x43d7ee,   -0x448ec0,   -0x454592,   -0x45fc64,   -0x46b336,
+   -0x476a08,   -0x4820da,   -0x48d7ac,   -0x498e7e,   -0x4a4550,   -0x4afc22,
+   -0x4bb2f4,   -0x4c69c6,   -0x4d2098,   -0x4dd76a,   -0x4e8e3c,   -0x4f450e,
+   -0x4ffbe0,   -0x50b2b2,   -0x516984,   -0x522056,   -0x52d728,   -0x538dfa,
+   -0x5444cc,   -0x54fb9e,   -0x55b270,   -0x566942,   -0x572014,   -0x57d6e6,
+   -0x588db8,   -0x59448a,   -0x59fb5c,   -0x5ab22e,
+ };
+
+const int Cb_g_tab[(MAXJSAMPLE+1) * sizeof(int)] ={
+    0x2c8d00,    0x2c34e6,    0x2bdccc,    0x2b84b2,    0x2b2c98,    0x2ad47e,
+    0x2a7c64,    0x2a244a,    0x29cc30,    0x297416,    0x291bfc,    0x28c3e2,
+    0x286bc8,    0x2813ae,    0x27bb94,    0x27637a,    0x270b60,    0x26b346,
+    0x265b2c,    0x260312,    0x25aaf8,    0x2552de,    0x24fac4,    0x24a2aa,
+    0x244a90,    0x23f276,    0x239a5c,    0x234242,    0x22ea28,    0x22920e,
+    0x2239f4,    0x21e1da,    0x2189c0,    0x2131a6,    0x20d98c,    0x208172,
+    0x202958,    0x1fd13e,    0x1f7924,    0x1f210a,    0x1ec8f0,    0x1e70d6,
+    0x1e18bc,    0x1dc0a2,    0x1d6888,    0x1d106e,    0x1cb854,    0x1c603a,
+    0x1c0820,    0x1bb006,    0x1b57ec,    0x1affd2,    0x1aa7b8,    0x1a4f9e,
+    0x19f784,    0x199f6a,    0x194750,    0x18ef36,    0x18971c,    0x183f02,
+    0x17e6e8,    0x178ece,    0x1736b4,    0x16de9a,    0x168680,    0x162e66,
+    0x15d64c,    0x157e32,    0x152618,    0x14cdfe,    0x1475e4,    0x141dca,
+    0x13c5b0,    0x136d96,    0x13157c,    0x12bd62,    0x126548,    0x120d2e,
+    0x11b514,    0x115cfa,    0x1104e0,    0x10acc6,    0x1054ac,    0x0ffc92,
+    0x0fa478,    0x0f4c5e,    0x0ef444,    0x0e9c2a,    0x0e4410,    0x0debf6,
+    0x0d93dc,    0x0d3bc2,    0x0ce3a8,    0x0c8b8e,    0x0c3374,    0x0bdb5a,
+    0x0b8340,    0x0b2b26,    0x0ad30c,    0x0a7af2,    0x0a22d8,    0x09cabe,
+    0x0972a4,    0x091a8a,    0x08c270,    0x086a56,    0x08123c,    0x07ba22,
+    0x076208,    0x0709ee,    0x06b1d4,    0x0659ba,    0x0601a0,    0x05a986,
+    0x05516c,    0x04f952,    0x04a138,    0x04491e,    0x03f104,    0x0398ea,
+    0x0340d0,    0x02e8b6,    0x02909c,    0x023882,    0x01e068,    0x01884e,
+    0x013034,    0x00d81a,    0x008000,    0x0027e6,   -0x003034,   -0x00884e,
+   -0x00e068,   -0x013882,   -0x01909c,   -0x01e8b6,   -0x0240d0,   -0x0298ea,
+   -0x02f104,   -0x03491e,   -0x03a138,   -0x03f952,   -0x04516c,   -0x04a986,
+   -0x0501a0,   -0x0559ba,   -0x05b1d4,   -0x0609ee,   -0x066208,   -0x06ba22,
+   -0x07123c,   -0x076a56,   -0x07c270,   -0x081a8a,   -0x0872a4,   -0x08cabe,
+   -0x0922d8,   -0x097af2,   -0x09d30c,   -0x0a2b26,   -0x0a8340,   -0x0adb5a,
+   -0x0b3374,   -0x0b8b8e,   -0x0be3a8,   -0x0c3bc2,   -0x0c93dc,   -0x0cebf6,
+   -0x0d4410,   -0x0d9c2a,   -0x0df444,   -0x0e4c5e,   -0x0ea478,   -0x0efc92,
+   -0x0f54ac,   -0x0facc6,   -0x1004e0,   -0x105cfa,   -0x10b514,   -0x110d2e,
+   -0x116548,   -0x11bd62,   -0x12157c,   -0x126d96,   -0x12c5b0,   -0x131dca,
+   -0x1375e4,   -0x13cdfe,   -0x142618,   -0x147e32,   -0x14d64c,   -0x152e66,
+   -0x158680,   -0x15de9a,   -0x1636b4,   -0x168ece,   -0x16e6e8,   -0x173f02,
+   -0x17971c,   -0x17ef36,   -0x184750,   -0x189f6a,   -0x18f784,   -0x194f9e,
+   -0x19a7b8,   -0x19ffd2,   -0x1a57ec,   -0x1ab006,   -0x1b0820,   -0x1b603a,
+   -0x1bb854,   -0x1c106e,   -0x1c6888,   -0x1cc0a2,   -0x1d18bc,   -0x1d70d6,
+   -0x1dc8f0,   -0x1e210a,   -0x1e7924,   -0x1ed13e,   -0x1f2958,   -0x1f8172,
+   -0x1fd98c,   -0x2031a6,   -0x2089c0,   -0x20e1da,   -0x2139f4,   -0x21920e,
+   -0x21ea28,   -0x224242,   -0x229a5c,   -0x22f276,   -0x234a90,   -0x23a2aa,
+   -0x23fac4,   -0x2452de,   -0x24aaf8,   -0x250312,   -0x255b2c,   -0x25b346,
+   -0x260b60,   -0x26637a,   -0x26bb94,   -0x2713ae,   -0x276bc8,   -0x27c3e2,
+   -0x281bfc,   -0x287416,   -0x28cc30,   -0x29244a,   -0x297c64,   -0x29d47e,
+   -0x2a2c98,   -0x2a84b2,   -0x2adccc,   -0x2b34e6,
+ };
+
+
+/* We assume that right shift corresponds to signed division by 2 with
+ * rounding towards minus infinity.  This is correct for typical "arithmetic
+ * shift" instructions that shift in copies of the sign bit.  But some
+ * C compilers implement >> with an unsigned shift.  For these machines you
+ * must define RIGHT_SHIFT_IS_UNSIGNED.
+ * RIGHT_SHIFT provides a proper signed right shift of an INT32 quantity.
+ * It is only applied with constant shift counts.  SHIFT_TEMPS must be
+ * included in the variables of any routine using RIGHT_SHIFT.
+ */
+
+#ifdef RIGHT_SHIFT_IS_UNSIGNED
+#define SHIFT_TEMPS	INT32 shift_temp;
+#define RIGHT_SHIFT(x,shft)  \
+	((shift_temp = (x)) < 0 ? \
+	 (shift_temp >> (shft)) | ((~((INT32) 0)) << (32-(shft))) : \
+	 (shift_temp >> (shft)))
+#else
+#define SHIFT_TEMPS
+#define RIGHT_SHIFT(x,shft)	((x) >> (shft))
+#endif
+
+
+METHODDEF(void)
+ycc_rgb_convert_argb (j_decompress_ptr cinfo,
+                 JSAMPIMAGE input_buf, JDIMENSION input_row,
+                 JSAMPARRAY output_buf, int num_rows)
+{
+  JDIMENSION num_cols = cinfo->output_width;
+  JSAMPLE * range_limit = cinfo->sample_range_limit;
+
+  SHIFT_TEMPS
+
+  /* This is used if we don't have SSE2 */
+
+  while (--num_rows >= 0) {
+    JSAMPROW inptr0 = input_buf[0][input_row];
+    JSAMPROW inptr1 = input_buf[1][input_row];
+    JSAMPROW inptr2 = input_buf[2][input_row];
+    input_row++;
+    uint32_t *outptr = (uint32_t *) *output_buf++;
+    for (JDIMENSION col = 0; col < num_cols; col++) {
+      int y  = GETJSAMPLE(inptr0[col]);
+      int cb = GETJSAMPLE(inptr1[col]);
+      int cr = GETJSAMPLE(inptr2[col]);
+      JSAMPLE * range_limit_y = range_limit + y;
+      /* Range-limiting is essential due to noise introduced by DCT losses. */
+      outptr[col] = 0xFF000000 |
+                    ( range_limit_y[Cr_r_tab[cr]] << 16 ) |
+                    ( range_limit_y[((int) RIGHT_SHIFT(Cb_g_tab[cb] + Cr_g_tab[cr], SCALEBITS))] << 8 ) |
+                    ( range_limit_y[Cb_b_tab[cb]] );
+    }
+  }
+}
+#endif
+
+
 ///*************** Inverted CMYK -> RGB conversion *************************
 /// Input is (Inverted) CMYK stored as 4 bytes per pixel.
 /// Output is RGB stored as 3 bytes per pixel.