~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Open Mash Cross Reference
mash/codec/jpeg/jpeg.cc

Component: ~ [ mash ] ~ [ apps ] ~ [ gsm ] ~ [ lib ] ~ [ otcl ] ~ [ srm ] ~ [ tcl8.3 ] ~ [ tclcl ] ~ [ tk8.3 ] ~ [ tutorials ] ~

  1 /*
  2  * jpeg.cc --
  3  *
  4  *      JPEG decoder (4:1:1 and 4:2:2, Pixel and DCT).
  5  */
  6 
  7 /*
  8  * This code is derived from the Independent JPEG Group's JPEG software:
  9  *
 10  * Copyright (C) 1991, 1992, Thomas G. Lane.
 11  * This file is part of the Independent JPEG Group's software.
 12  * For conditions of distribution and use, see the accompanying
 13  * README.IJPG file.
 14  */
 15 
 16 #include "codec/jpeg/jpeg.h"
 17 #include "misc/bsd-endian.h"
 18 #include "codec/dct.h"
 19 
 20 #include <stdlib.h>
 21 #include <stdio.h>
 22 #ifdef WIN32
 23 #include <winsock.h>
 24 #else
 25 #include <sys/param.h>
 26 #include <netinet/in.h>
 27 #endif
 28 #include <string.h>
 29 
 30 #define NCC 6   /* # of components to check for CR */
 31 #define BMB 6   /* # of (8x8) blocks in a "macroblock" [2xY+U+V] */
 32 #define DCT_GRAY        (0x80 * 8)      // DCT gray value
 33 
 34 #define EVEN(x) ((x & 1) == 0)
 35 #define ODD(x)  ((x & 1) == 1)
 36 
 37 //
 38 // derived decoders (420-pixel, 422-pixel, 420-DCT, and 422-DCT)
 39 //
 40 
 41 /*
 42  * Read the next 16 bits off the bit string into the bit buffer.
 43  * Skip over zero-stuffed ff's but make no attempt to verify
 44  * that they aren't some other marker (which shouldn't be in the
 45  * middle of a block anyway).
 46  */
 47 #define HUFFRQ(bb) \
 48  { \
 49         register int v; \
 50         register const u_char *cp = inb_; \
 51  \
 52         bb <<= 16; \
 53         v = *cp++; \
 54         if (v == 0xff) ++cp; \
 55         bb |= v << 8; \
 56         v = *cp++; \
 57         if (v == 0xff) ++cp; \
 58         bb |= v; \
 59         inb_ = cp; \
 60  \
 61 }
 62 
 63 #define MASK(s) ((1 << (s)) - 1)
 64 
 65 #define HUFF_DECODE(ht, nbb, bb, result) { \
 66         register int s_, v_; \
 67  \
 68         if (nbb < 16) { \
 69                 HUFFRQ(bb); \
 70                 nbb += 16; \
 71         } \
 72         v_ = (bb >> (nbb - 16)) & 0xffff; \
 73         s_ = (ht)[v_]; \
 74         nbb -= (s_ >> 8); \
 75         result = s_ & 0xff; \
 76  }
 77 
 78 #define GET_BITS(n, nbb, bb, result) \
 79 { \
 80         nbb -= n; \
 81         if (nbb < 0)  { \
 82                 HUFFRQ(bb); \
 83                 nbb += 16; \
 84         } \
 85         (result) = ((bb >> nbb) & MASK(n)); \
 86 }
 87 
 88 #define SKIP_BITS(n, nbb, bb) \
 89 { \
 90         nbb -= n; \
 91         if (nbb < 0)  { \
 92                 HUFFRQ(bb); \
 93                 nbb += 16; \
 94         } \
 95 }
 96 
 97 class JpegDecoder_420 : public JpegPixelDecoder {
 98 public:
 99         JpegDecoder_420(const config&, int, int);
100         virtual int decode(const u_char* in, int len, int type,
101                            u_char *marks, int mark);
102 };
103 
104 class JpegDecoder_422 : public JpegPixelDecoder {
105 public:
106         JpegDecoder_422(const config&, int, int);
107         virtual int decode(const u_char* in, int len, int type,
108                            u_char *marks, int mark);
109 };
110 
111 class JpegDCTDecoder_420 : public JpegDCTDecoder {
112 public:
113         JpegDCTDecoder_420(const config&, int, int);
114         virtual int decode(const u_char* in, int len, int type,
115                            u_char *marks, int mark);
116 };
117 
118 class JpegDCTDecoder_422 : public JpegDCTDecoder {
119  public:
120         JpegDCTDecoder_422(const config&, int, int);
121         virtual int decode(const u_char* in, int len, int type,
122                            u_char *marks, int mark);
123 };
124 
125 class JpegDCTDecoder_True422 : public JpegDCTDecoder {
126 public:
127         JpegDCTDecoder_True422(const config&, int, int);
128         virtual int decode(const u_char* in, int len, int type,
129                            u_char *marks, int mark);
130 };
131 
132 JpegPixelDecoder::JpegPixelDecoder(const config &c, int dec, int ow, int oh)
133                  :JpegDecoder(c, dec, ow, oh)
134 {
135         int ns = NCC * owidth_ * oheight_ / 64; // # blocks
136         cache_ = new short[ns];
137         /*
138          * Initialize to some "large value" so threshold
139          * is exceeded on first pass.
140          */
141         memset(cache_, 0x7f, ns * sizeof(*cache_));
142         setlrskips();
143 }
144 
145 JpegPixelDecoder::~JpegPixelDecoder()
146 {
147         delete[] cache_;
148         delete[] frm_;
149 }
150 
151 JpegDCTDecoder::JpegDCTDecoder(const config& c, int dec, int ow, int oh)
152                :JpegDecoder(c, dec, ow, oh)
153 {
154         setlrskips();
155 }
156 
157 JpegDCTDecoder::~JpegDCTDecoder()
158 {
159         delete[] frm_;
160 }
161 
162 JpegDecoder_420::JpegDecoder_420(const config& c, int ow, int oh)
163                 :JpegPixelDecoder(c, 420, ow, oh)
164 {
165         int n = osize_ + osize_ / 2;
166         frm_ = new u_char[n];           // pixel store
167         memset(frm_, 0x80, n);
168         dct_unbias_ = 0;
169 }
170 
171 JpegDCTDecoder_420::JpegDCTDecoder_420(const config& c, int ow, int oh)
172                    :JpegDCTDecoder(c, 420, ow, oh)
173 {
174         int n = osize_ + osize_ / 2;
175         frm_ = new short[n];            // DCT store
176         memset(frm_, 0x0, n * sizeof(short));
177         dct_unbias_ = 1;
178 
179         short *sp = (short *)frm_;
180         for (register int i = 0; i < n / (BMB * 64) ; i++) {
181                 *sp = DCT_GRAY;
182                 sp += 64;
183                 *sp = DCT_GRAY;
184                 sp += 64;
185                 *sp = DCT_GRAY;
186                 sp += 64;
187                 *sp = DCT_GRAY;
188                 sp += 64;
189                 *sp = DCT_GRAY;
190                 sp += 64;
191                 *sp = DCT_GRAY;
192                 sp += 64;
193         }
194 }
195 
196 JpegDecoder_422::JpegDecoder_422(const config& c, int ow, int oh)
197                 :JpegPixelDecoder(c, 422, ow, oh)
198 {
199         int n = osize_ * 2;
200         frm_ = new u_char[n];           // pixel store
201         memset(frm_, 0x80, n);
202         dct_unbias_ = 0;
203 }
204 
205 JpegDCTDecoder_422::JpegDCTDecoder_422(const config& c, int ow, int oh)
206                    :JpegDCTDecoder(c, 422, ow, oh)
207 {
208         int n = osize_ * 2;
209         frm_ = new short[n];            // DCT store
210         memset(frm_, 0x0, n * sizeof(short));
211         dct_unbias_ = 1;
212 
213         short *sp = (short*)frm_;
214         for (register int i = 0; i < n / (BMB * 64) ; i++) {
215                 *sp = DCT_GRAY;
216                 sp += 64;
217                 *sp = DCT_GRAY;
218                 sp += 64;
219                 *sp = DCT_GRAY;
220                 sp += 64;
221                 *sp = DCT_GRAY;
222                 sp += 64;
223                 *sp = DCT_GRAY;
224                 sp += 64;
225                 *sp = DCT_GRAY;
226                 sp += 64;
227         }
228 }
229 
230 JpegPixelDecoder* JpegPixelDecoder::create(const config& c, int ow, int oh)
231 {
232         if (c.ncomp == 3 && c.comp[0].hsf == 2 &&
233             c.comp[1].hsf == 1 && c.comp[1].vsf == 1 &&
234             c.comp[2].hsf == 1 && c.comp[2].vsf == 1) {
235 
236                 // 420 decoder, RTP type 1 or 65, vsf = 2
237                 if (c.comp[0].vsf == 2)
238                                 return (new JpegDecoder_420(c, ow, oh));
239 
240                 // 422 decoder, RTP type 0 or 64, vsf = 1
241                 if (c.comp[0].vsf == 1)
242                                 return (new JpegDecoder_422(c, ow, oh));
243         }
244         return (0);
245 }
246 
247 JpegDCTDecoder* JpegDCTDecoder::create(const config& c, int ow, int oh)
248 {
249         if (c.ncomp == 3 && c.comp[0].hsf == 2 &&
250             c.comp[1].hsf == 1 && c.comp[1].vsf == 1 &&
251             c.comp[2].hsf == 1 && c.comp[2].vsf == 1) {
252 
253                 // 420 decoder, RTP type 1 or 65, vsf = 2
254                 if (c.comp[0].vsf == 2)
255                         return (new JpegDCTDecoder_420(c, ow, oh));
256 
257                 // 422 decoder, RTP type 0 or 64, vsf = 1
258                 if (c.comp[0].vsf == 1)
259                         return (new JpegDCTDecoder_422(c, ow, oh));
260         }
261         return (0);
262 }
263 
264 JpegDCTDecoder* JpegDCTDecoder::true_create(const config& c, int ow, int oh)
265 {
266   if (c.ncomp == 3 && c.comp[0].hsf == 2 &&
267       c.comp[1].hsf == 1 && c.comp[1].vsf == 1 &&
268       c.comp[2].hsf == 1 && c.comp[2].vsf == 1) {
269 
270                 // 420 decoder, RTP type 1 or 65, vsf = 2
271     if (c.comp[0].vsf == 2)
272       return (new JpegDCTDecoder_420(c, ow, oh));
273 
274                 // 422 decoder, RTP type 0 or 64, vsf = 1
275     if (c.comp[0].vsf == 1)
276       return (new JpegDCTDecoder_True422(c, ow, oh));
277   }
278   return (0);
279 }
280 
281 int quality_to_qfactor(int v)
282 {
283         if (v < 1)
284                 v = 5000;
285         else if (v < 50)
286                 v = 5000 / v;
287         else if (v < 100)
288                 v = 200 - v * 2;
289         else
290                 v = 1;
291 
292         return (v);
293 }
294 
295 
296 /*
297  * Table K.1 from JPEG spec.
298  */
299 static const int jpeg_luma_quantizer[64] = {
300         16, 11, 10, 16, 24, 40, 51, 61,
301         12, 12, 14, 19, 26, 58, 60, 55,
302         14, 13, 16, 24, 40, 57, 69, 56,
303         14, 17, 22, 29, 51, 87, 80, 62,
304         18, 22, 37, 56, 68, 109, 103, 77,
305         24, 35, 55, 64, 81, 104, 113, 92,
306         49, 64, 78, 87, 103, 121, 120, 101,
307         72, 92, 95, 98, 112, 100, 103, 99
308 };
309 
310 static const short jpeg_luma_quantizer_short[64] = {
311         16, 11, 10, 16, 24, 40, 51, 61,
312         12, 12, 14, 19, 26, 58, 60, 55,
313         14, 13, 16, 24, 40, 57, 69, 56,
314         14, 17, 22, 29, 51, 87, 80, 62,
315         18, 22, 37, 56, 68, 109, 103, 77,
316         24, 35, 55, 64, 81, 104, 113, 92,
317         49, 64, 78, 87, 103, 121, 120, 101,
318         72, 92, 95, 98, 112, 100, 103, 99
319 };
320 
321 /*
322  * Table K.2 from JPEG spec.
323  */
324 static const int jpeg_chroma_quantizer[64] = {
325         17, 18, 24, 47, 99, 99, 99, 99,
326         18, 21, 26, 66, 99, 99, 99, 99,
327         24, 26, 56, 99, 99, 99, 99, 99,
328         47, 66, 99, 99, 99, 99, 99, 99,
329         99, 99, 99, 99, 99, 99, 99, 99,
330         99, 99, 99, 99, 99, 99, 99, 99,
331         99, 99, 99, 99, 99, 99, 99, 99,
332         99, 99, 99, 99, 99, 99, 99, 99,
333 };
334 
335 static const short jpeg_chroma_quantizer_short[64] = {
336         17, 18, 24, 47, 99, 99, 99, 99,
337         18, 21, 26, 66, 99, 99, 99, 99,
338         24, 26, 56, 99, 99, 99, 99, 99,
339         47, 66, 99, 99, 99, 99, 99, 99,
340         99, 99, 99, 99, 99, 99, 99, 99,
341         99, 99, 99, 99, 99, 99, 99, 99,
342         99, 99, 99, 99, 99, 99, 99, 99,
343         99, 99, 99, 99, 99, 99, 99, 99,
344 };
345 
346 void jpeg_qt(int q, int* out, const int* in)
347 {
348         q = quality_to_qfactor(q);
349         for (int i = 0; i < 64; i++) {
350                 int val = (q * in[i] + 50) / 100;
351                 /*
352                  * Baseline JPEG restricts range to [1,255].
353                  */
354                 if (val < 1)
355                         val = 1;
356                 else if (val > 255)
357                         val = 255;
358                 out[i] = val;
359         }
360 }
361 
362 void jpeg_luma_qt(int q, int* qt)
363 {
364         jpeg_qt(q, qt, jpeg_luma_quantizer);
365 }
366 
367 void jpeg_chroma_qt(int q, int* qt)
368 {
369         jpeg_qt(q, qt, jpeg_chroma_quantizer);
370 }
371 
372 static const unsigned char dc_luminance_bits[17] =
373     { /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
374 static const unsigned char dc_luminance_val[] =
375     { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
376 
377 static const unsigned char dc_chrominance_bits[17] =
378     { /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
379 static const unsigned char dc_chrominance_val[] =
380     { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
381 
382 static const unsigned char ac_luminance_bits[17] =
383     { /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d };
384 static const unsigned char ac_luminance_val[] =
385     { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
386       0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
387       0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
388       0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
389       0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
390       0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
391       0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
392       0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
393       0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
394       0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
395       0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
396       0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
397       0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
398       0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
399       0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
400       0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
401       0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
402       0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
403       0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
404       0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
405       0xf9, 0xfa };
406 
407 static const unsigned char ac_chrominance_bits[17] =
408     { /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 };
409 static const unsigned char ac_chrominance_val[] =
410     { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
411       0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
412       0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
413       0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
414       0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
415       0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
416       0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
417       0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
418       0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
419       0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
420       0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
421       0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
422       0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
423       0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
424       0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
425       0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
426       0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
427       0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
428       0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
429       0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
430       0xf9, 0xfa };
431 
432 void JpegDecoder::defaults(JpegDecoder::config& c)
433 {
434         c.width = 0;
435         c.height = 0;
436 
437         c.precision = 8;
438         c.ncomp = 3;
439         /* Y */
440         c.comp[0].id = 0;
441         c.comp[0].hsf = 2;
442         c.comp[0].vsf = 1;      // RTP type 0, 4:2:2 JPEG
443         c.comp[0].qno = 0;
444         /* U */
445         c.comp[1].id = 1;
446         c.comp[1].hsf = 1;
447         c.comp[1].vsf = 1;
448         c.comp[1].qno = 1;
449         /* V */
450         c.comp[2].id = 2;
451         c.comp[2].hsf = 1;
452         c.comp[2].vsf = 1;
453         c.comp[2].qno = 1;
454 
455         c.dc_huffbits[0] = dc_luminance_bits;
456         c.dc_huffval[0] = dc_luminance_val;
457         c.dc_huffbits[1] = dc_chrominance_bits;
458         c.dc_huffval[1] = dc_chrominance_val;
459         c.ac_huffbits[0] = ac_luminance_bits;
460         c.ac_huffval[0] = ac_luminance_val;
461         c.ac_huffbits[1] = ac_chrominance_bits;
462         c.ac_huffval[1] = ac_chrominance_val;
463         for (int i = 2; i < 4; ++i) {
464                 c.ac_huffbits[i] = 0;
465                 c.ac_huffval[i] = 0;
466                 c.dc_huffbits[i] = 0;
467                 c.dc_huffval[i] = 0;
468         }
469         c.comp[0].dc_tbl_no = 0;
470         c.comp[0].ac_tbl_no = 0;
471         c.comp[1].dc_tbl_no = 1;
472         c.comp[1].ac_tbl_no = 1;
473         c.comp[2].dc_tbl_no = 1;
474         c.comp[2].ac_tbl_no = 1;
475 }
476 
477 /*
478  * Set the quantizer for this configuration.
479  * Q is the IJPG quality factor, which has a value in [0,100].
480  */
481 void JpegDecoder::quantizer(JpegDecoder::config& c, int q)
482 {
483         jpeg_luma_qt(q, c.qtab[0]);
484         jpeg_chroma_qt(q, c.qtab[1]);
485         memset(c.qtab[2], 0, sizeof(c.qtab[2]));
486         memset(c.qtab[3], 0, sizeof(c.qtab[3]));
487 }
488 
489 int JpegDecoder::q_to_thresh(int q)
490 {
491         int s = q / 10;
492         if (q <= 30 || q >= 80)
493                 s += 1;
494         return (s);
495 }
496 
497 JpegDecoder::JpegDecoder(const config& c, int csss, int ow, int oh)
498         : ndblk_(0), csss_(csss), width_(-1), height_(-1),
499           owidth_(ow), oheight_(oh), color_(1), thresh_(0), cthresh_(6)
500 {
501         // initialize huffman tables
502         for (int i = NUM_HUFF_TBLS; --i >= 0; ) {
503                 dcht_[i] = 0;
504                 acht_[i] = 0;
505         }
506         memset((char*)comp_, 0, sizeof(comp_));
507         init(c);
508 }
509 
510 JpegDecoder::~JpegDecoder()
511 {
512         freehufftab();
513 }
514 
515 /*
516  * init() is called only by the constructor above
517  */
518 void JpegDecoder::init(const config& c)
519 {
520         rlen_ = 0;
521 
522         osize_ = owidth_ * oheight_;    // output size
523         memcpy((char*)qt_, (char*)c.qtab, sizeof(qt_));
524         int i;
525         for (i = 0; i < 4; ++i)
526                 rdct_fold_q(qt_[i], fqt_[i]);
527 
528         width_ = c.width;               // input w/h
529         height_ = c.height;
530         size_ = width_ * height_;       // input size
531 
532         ncomp_ = c.ncomp;/*FIXME*/
533         for (i = ncomp_; --i >= 0; ) {
534                 int id = c.comp[i].id;
535                 comp_[id].hsf = c.comp[i].hsf;
536                 comp_[id].vsf = c.comp[i].vsf;
537                 comp_[id].qno = c.comp[i].qno;
538                 comp_[id].dc_tbl_no = c.comp[i].dc_tbl_no;
539                 comp_[id].ac_tbl_no = c.comp[i].ac_tbl_no;
540         }
541         /*
542          * FIXME should check if huffman table won't change
543          * before reallocating.
544          */
545         freehufftab();
546         for (i = 0; i < 4; ++i) {
547                 if (c.dc_huffval[i] != 0) {
548                         int id = c.comp[i].id;
549                         dcht_[id] = huffbuild(c.dc_huffbits[i],
550                                               c.dc_huffval[i]);
551                 }
552                 if (c.ac_huffval[i] != 0) {
553                         int id = c.comp[i].id;
554                         acht_[id] = huffbuild(c.ac_huffbits[i],
555                                               c.ac_huffval[i]);
556                 }
557         }
558 
559         int maxh = 1;
560         int maxv = 1;
561         for (i = ncomp_; --i >= 0; ) {
562                 if (maxh < comp_[i].hsf)
563                         maxh = comp_[i].hsf;
564                 if (maxv < comp_[i].vsf)
565                         maxv = comp_[i].vsf;
566         }
567 
568         // # rows and cols in input JPEG image
569         mcu_cols_ = (width_ + 8 * maxh - 1) / (8 * maxh);
570         mcu_rows_ = (height_ + 8 * maxv - 1) / (8 * maxv);
571 
572         if (compute_margins(maxh, maxv) != 0)  {
573                 fprintf(stderr,
574                         "JpegDecoder::init: couldn't compute margins\n");
575         }
576 
577 }
578 
579 
580 int JpegDecoder::compute_margins(int maxh, int maxv)
581 {
582         /*
583          * Embed one image size in a bigger one.
584          * (extra areas will already be gray from init() )
585          */
586         margin& m = margin_;
587         m.top = m.left = m.right = 0;
588         lcrop_ = 0;
589         rcrop_ = mcu_cols_;
590         topcrop_ = 0;
591         botcrop_ = mcu_rows_;
592 
593         int dx = owidth_ - width_;
594         int dy = oheight_ - height_;
595 
596         /*
597          * If output size is smaller that intput, crop input image to fit
598          * output size, otherwise try and center the image in the larger
599          * frame, making sure to align on macroblock (16x16) boundaries.
600          */
601         if (dx < 0) {
602                 dx = -dx;
603                 /* Bail if can't align on block boundary. */
604                 if (dx % 8 != 0)
605                         return (-1);
606 
607                 int q = dx / 16;
608                 if (q % 2 != 0) {
609                         /* Can't center crop horizontally */
610                         lcrop_ = (((dx - 16) / 2) + 8 * maxh - 1) / (8 * maxh);
611                         rcrop_ = mcu_cols_ - lcrop_ + 1;
612                 } else {
613                         /* Center crop horizontally */
614                         lcrop_ = ((dx / 2) + 8 * maxh - 1) / (8 * maxh);
615                         rcrop_ = mcu_cols_ - lcrop_;
616                 }
617         } else {
618                 if (dx % 8 != 0)
619                         return (-1);
620 
621                 /* Know dx is multiple of 8 at least */
622                 if (dx % 16 == 8) {
623                         /* crop one column and bias dx */
624                         mcu_cols_--;
625                         dx -= 8;
626                 }
627 
628                 int q = dx / 16;
629                 if (q % 2 != 0) {
630                         /* Can't center horizontally */
631                         m.right = (dx - 16) / 2;
632                         m.left = (dx + 16) / 2;
633                 } else {
634                         /* Center horizontally */
635                         m.right = m.left = dx / 2;
636                 }
637         }
638 
639         if (dy < 0) {
640                 dy = -dy;
641                 /* Bail if can't align on block boundary. */
642                 if (dy % 8 != 0)
643                         return (-1);
644 
645                 int q = dy / 16;
646                 if (q % 2 != 0) {
647                         /* Can't center crop vertically */
648                         topcrop_ = (((dy - 16) / 2) + 8 * maxv - 1) /
649                                 (8 * maxv);
650                         botcrop_ = mcu_rows_ - topcrop_ + 1;
651                 } else {
652                         /* Center crop vertically */
653                         topcrop_ = ((dy / 2) + 8 * maxv - 1) / (8 * maxv);
654                         botcrop_ = mcu_rows_ - topcrop_;
655                 }
656         } else {
657                 /* Bail if can't align on block boundary. */
658                 if (dy % 8 != 0)
659                         return (-1);
660                 /* Know dy is multiple of 8 at least */
661                 if (dy % 16 == 8) {
662                         /* crop one row and bias dy */
663                         mcu_rows_--;
664                         dy -= 8;
665                 }
666                 int q = dy / 16;
667                 if (q % 2 != 0) {
668                         /* Can't center vertically */
669                         m.top = (dy - 16) / 2;
670                 } else {
671                         /* Center vertically */
672                         m.top = dy / 2;
673                 }
674         }
675 
676 
677         return (0);
678 }
679 
680 void JpegDCTDecoder::setlrskips()
681 {
682         margin& m = margin_;
683 
684         // marks in CRvec relate to 16x16 DCT blocks
685 
686         m.flskip = m.left / 16 * (BMB * 64);
687         m.frskip = m.right / 16 * (BMB * 64);
688         m.ftopskip = m.top / 16 * owidth_ / 16 * (BMB * 64);
689         m.marktopskip = m.top / 16 * owidth_ / 16;
690         m.marklskip = m.left / 16;
691         m.markrskip = m.right / 16;
692 }
693 
694 void JpegPixelDecoder::setlrskips()
695 {
696         margin& m = margin_;
697 
698         m.ylskip = m.left;
699         m.uvlskip = m.left / 2;
700 
701         m.yrskip = m.right;
702         m.uvrskip = m.right / 2;
703 
704         m.ytopskip = m.top * owidth_;
705         if (csss_ == 422)
706                 m.uvtopskip = m.ytopskip / 128 * 64;
707         else
708                 m.uvtopskip = m.ytopskip / 256 * 64;
709 
710 
711         m.marktopskip = m.top / 8 * owidth_ / 8;
712         m.marklskip = m.left / 8;
713         m.markrskip = m.right / 8;
714 }
715 
716 void JpegDecoder::freehufftab()
717 {
718         for (int i = 0; i < 4; ++i) {
719                 if (dcht_[i] != 0)
720                         delete[] dcht_[i];
721                 if (acht_[i] != 0)
722                         delete[] acht_[i];
723         }
724 }
725 
726 #if NCC != 6
727 
728 @BUG in blkdiff@
729 #endif
730 #define ABS(t) ((t) - (((t) >> 31 & (t)) << 1))
731 inline int zag_blkdiff(short* blk, short* ref)
732 {
733         int t = blk[0] - ref[0];
734         int d = ABS(t);
735         t = blk[1] - ref[8];
736         d += ABS(t);
737         t = blk[2] - ref[1];
738         d += ABS(t);
739         t = blk[3] - ref[2];
740         d += ABS(t);
741         t = blk[4] - ref[9];
742         d += ABS(t);
743         t = blk[5] - ref[16];
744         d += ABS(t);
745         return (d);
746 }
747 
748 inline int inorder_blkdiff(short* blk, short* ref)
749 {
750         int t = blk[0] - ref[0];
751         int d = ABS(t);
752         t = blk[1] - ref[1];
753         d += ABS(t);
754         t = blk[2] - ref[2];
755         d += ABS(t);
756         t = blk[3] - ref[3];
757         d += ABS(t);
758         t = blk[4] - ref[4];
759         d += ABS(t);
760         t = blk[5] - ref[5];
761         d += ABS(t);
762         return (d);
763 }
764 
765 #ifdef notdef
766 /* FIXME this is negligibly faster than above, and has a bug */
767 inline int blkdiff(short* blk, short* cache)
768 {
769         u_int* p0 = (u_int*)blk;
770         u_int* p1 = (u_int*)cache;
771 
772         int m = ~0x80008000;
773         int t = (p0[0] >> 1) & m;
774         t += (~p1[0] >> 1) & m;
775         int v = t << 17 >> 17;
776         int d = ABS(v);
777         t = (t << 1) >> 17;
778         d += ABS(v);
779 
780         t = (p0[1] >> 1) & m;
781         t += (~p1[1] >> 1) & m;
782         v = t << 17 >> 17;
783         d += ABS(v);
784         t = (t << 1) >> 17;
785         d += ABS(v);
786 
787         t = (p0[2] >> 1) & m;
788         t += (~p1[2] >> 1) & m;
789         v = t << 17 >> 17;
790         d += ABS(v);
791         t = (t << 1) >> 17;
792         d += ABS(v);
793 
794         return (d);
795 }
796 #endif
797 
798 int JpegDecoder::rdqt(const u_char* p)
799 {
800         int len = *p++ << 8;
801         len |= *p++;
802 
803         const u_char* ep = p + len - 2;
804         while (p < ep) {
805                 int n = *p++;
806                 int prec = n >> 4;
807                 n &= 0x0f;
808                 if (n >= 4) {
809                         /*FIXME illegal number*/
810                         return (-1);
811                 }
812                 int qt[64];
813                 int i;
814                 for (i = 0; i < 64; i++) {
815                         int v = *p++;
816                         if (prec)
817                                 v = (v << 8) + *p++;
818                         qt[i] = v;
819                 }
820                 for (i = 0; i < 64; i++) {
821                         /* Compute new table only if it changed */
822                         int j = ROWZAG[i];
823                         if (qt[i] != qt_[n][j]) {
824                                 for (; i < 64; ++i) {
825                                         j = ROWZAG[i];
826                                         qt_[n][j] = qt[i];
827                                 }
828                                 rdct_fold_q(qt_[n], fqt_[n]);
829                                 break;
830                         }
831                 }
832         }
833         return (len);
834 }
835 
836 void JpegDecoder::restart()
837 {
838         int c;
839         nbb_ = 0;
840 
841         /* scan backward for a restart marker */
842         for (int i=-5; i<0; ++i) {
843             if (inb_[i] == 0xff && (((inb_[i+1] >= 0xd0 && inb_[i+1] <= 0xd7)
844                                      || inb_[i+1] == 0xd9))) {
845                         inb_=inb_+i;
846                         break;
847                 }
848         }
849         
850         /*FIXMEwhat if ff is sitting in bit buffer?*/
851         /* Scan for next JPEG marker */
852         do {
853                 do {                    /* skip any non-FF bytes */
854                         c = *inb_++;
855                 } while (c != 0xFF);
856                 do {
857                         /* skip any duplicate FFs */
858                         c = *inb_++;
859                 } while (c == 0xFF);
860         } while (c == 0);               /* repeat if it was a stuffed FF/00 */
861 
862         /* Re-initialize DC predictions to 0 */
863         comp_[0].dc = 0;
864         comp_[1].dc = 0;
865         comp_[2].dc = 0;
866 }
867 
868 const u_char* JpegDecoder::parseJFIF(const u_char* in)
869 {
870         int t;
871         while (in < end_) {
872                 if (*in++ != 0xff)
873                         continue;
874                 /*FIXME need more checks for buffer overflow*/
875                 switch (*in++) {
876 
877                 default:
878                         /* Don't know.  Keep looking for SOS. */
879                         continue;
880 
881                 case 0xdb:
882                         /* quantization table */
883                         t = rdqt(in);
884                         if (t < 0)
885                                 /*FIXME*/
886                                 return (end_);
887                         in += t;
888                         continue;
889 
890                 case 0xdd:
891                         /* restart interval definition */
892                         t = *in++ << 8;
893                         t |= *in++;
894 /* FIXME */
895 /* removed for now to avoid compiler warnings */
896 #if 0
897                         if (t != 4)
898                                 /* FIXME bad length */
899                                 ;
900 #endif
901                         rlen_ = *in++ << 8;
902                         rlen_ |= *in++;
903                         rcnt_ = 0;
904                         continue;
905 
906                 case 0xda:
907                         /* start-of-scan marker */
908                         if (in + 2 <= end_) {
909                                 /* skip over SOS */
910                                 int t = *in++ << 8;
911                                 t |= *in++;
912                                 in += (t - 2);
913                         }
914                         return (in);
915                 }
916         }
917         /*FIXME*/
918         return (end_);
919 }
920 
921 /*FIXME*/
922 #ifdef INT_64
923 #define MASK_DECL       INT_64 m0
924 #define MASK_VAL        m0
925 #define MASK_REF        &m0
926 
927 inline void JpegDecoder::rdct(int nc, register short *bp, INT_64 mask,
928                               u_char* pixels, int stride, int qno)
929 {
930 #ifdef notyet
931         if (nc == 2) {
932                 for (int k = 1; k < 64; ++k)
933                         if (mask & ((INT_64)1 << k)) {
934                                 int s = bp[k] * qt_[qno][k];
935                                 int dc = (bp[0] * qt_[qno][0] >> 3) + 128;
936                                 /*FIXME limit dc?*/
937                                 bv_rdct1(dc, bp, k, pixels, stride);
938                                 return;
939                         }
940         }
941 #endif
942         if (nc != 0)
943                 ::rdct(bp, mask, pixels, stride, fqt_[qno]);
944 #ifdef notdef
945         if (nc > cthresh_)
946                 ::rdct(bp, mask, pixels, stride, fqt_[qno]);
947         else if (nc > 0)
948                 bv_rdct(bp, mask, pixels, stride, qt_[qno]);
949 #endif
950 }
951 #else
952 #define MASK_DECL       u_int mask[2]
953 #define MASK_VAL        mask[0], mask[1]
954 #define MASK_REF        mask
955 inline void JpegDecoder::rdct(int nc, register short *bp, u_int m0, u_int m1,
956                               u_char* pixels, int stride, int qno)
957 {
958 #ifdef notyet
959         if (nc > cthresh_)
960                 ::rdct(bp, m0, m1, pixels, stride, fqt_[qno]);
961         else if (nc > 0)
962                 bv_rdct(bp, m0, m1, pixels, stride, qt_[qno]);
963 #else
964         if (nc != 0)
965                 ::rdct(bp, m0, m1, pixels, stride, fqt_[qno]);
966 #endif
967 }
968 #endif
969 
970 /*
971  * 422 Decoders
972  */
973 int JpegDecoder_422::decode(const u_char* in, int len, int type,
974                             u_char *marks, int mark)
975 {
976         inb_ = in;
977         end_ = in + len;
978         nbb_ = 0;
979 
980         /*
981          * If first symbol is a marker (a not a stuffed ff),
982          * assume a jfif header is present and parse it.
983          * FIXME this could change state that needs to be
984          * communicated back to caller.
985          */
986         if (in[0] == 0xff && in[1] != 0)
987                 inb_ = parseJFIF(inb_);
988 
989         huffreset();
990 
991         int q0 = comp_[0].qno;
992         int q1 = comp_[1].qno;
993         u_char* yp = frm_;
994         u_char* up = yp + osize_;
995         u_char* vp = up + osize_ / 2;
996         short* cache = cache_;
997         short blk[64];
998 
999         /* Skip top */
1000         margin& m = margin_;
1001         yp += m.ytopskip;
1002         up += m.uvtopskip;
1003         vp += m.uvtopskip;
1004         marks += m.marktopskip;
1005         cache += m.marktopskip * NCC;
1006 
1007         if (type == JPEG_ODD_FIELD) {
1008                 yp += owidth_;
1009                 up += owidth_ / 2;
1010                 vp += owidth_ / 2;
1011 
1012                 cache += NCC*mcu_rows_*mcu_cols_; // XXX
1013         }
1014 
1015         int rows;
1016         int ystride;
1017         int uvstride;
1018         int markstride;
1019 
1020         if (type == JPEG_FULL_FRAME) {
1021                 rows = mcu_rows_;
1022                 ystride = owidth_;
1023                 uvstride = owidth_ / 2;
1024                 markstride = 0;
1025         } else {
1026                 rows = mcu_rows_ / 2;
1027                 ystride = owidth_ * 2;
1028                 uvstride = owidth_;
1029                 // each byte in marks represents a 8x8 block. mcu_cols_ counts the number 
1030                 // of MCU (16x8) columns. The stride is therefore twice the mcu_cols_
1031                 markstride = 2*mcu_cols_;
1032         }
1033 
1034         // for each row (8-pixel high)
1035         for (int y = 0; y < rows; ++y) {
1036                 int ycrop = (y < topcrop_ || y >= botcrop_);
1037                 if (!ycrop) {
1038                         marks += m.marklskip;
1039                         yp += m.ylskip;
1040                         up += m.uvlskip;
1041                         vp += m.uvlskip;
1042                         cache += m.marklskip * NCC;
1043                 }
1044                 // for each column (16-pixel wide)
1045                 for (int x = 0; x < mcu_cols_; ++x) {
1046                         if (ycrop || x < lcrop_ || x >= rcrop_) {
1047                                 (void)huffskip(comp_[0]);
1048                                 (void)huffskip(comp_[0]);
1049                                 (void)huffskip(comp_[1]);
1050                                 (void)huffskip(comp_[2]);
1051                                 continue;
1052                         }
1053 
1054                         MASK_DECL;
1055                         /*
1056                          * If we're handling restart markers,
1057                          * check if we need to resync.
1058                          */
1059                         if (rlen_ != 0 && --rcnt_ <= 0) {
1060                                 rcnt_ = rlen_;
1061                                 restart();
1062                         }
1063 
1064                         // decode the left 8x8-pixel Y block
1065                         int nc = huffparse(comp_[0], blk, cache, MASK_REF);
1066                         int dontskip = nc;
1067                         cache += NCC;
1068                         rdct(nc, blk, MASK_VAL, yp, ystride, q0);
1069 
1070                         // decode the right 8x8-pixel Y block
1071                         nc = huffparse(comp_[0], blk, cache, MASK_REF,
1072                                        dontskip);
1073                         dontskip |= nc;
1074 
1075                         //dontskip = 1; // used only for measuring performance
1076 
1077                         cache += NCC;
1078                         rdct(nc, blk, MASK_VAL, yp + 8, ystride, q0);
1079 
1080                         // If we're line doubling, copy the pixels
1081                         if (type == JPEG_SINGLE_FIELD) {
1082                             u_char* ty = yp;
1083                             for (int i=0; i<8; i++) {
1084                                 memcpy(ty + owidth_, ty, 16);
1085                                 ty += 2*owidth_;
1086                             }
1087                         }
1088 
1089                         if (color_ && dontskip) {
1090                                 /*
1091                                  * If we found above that the luminance
1092                                  * planes exceeded the threshold, decode
1093                                  * the choma planes unconditionally.
1094                                  * Otherwise, see if they can be
1095                                  * suppressed too.
1096                                  */
1097                                 short dummy[6];
1098 
1099                                 // decode the 8x8-pixel Cb block (even
1100                                 // columns of the 16x8-pixel macroblock)
1101                                 nc = huffparse(comp_[1], blk, dummy, MASK_REF,
1102                                                1);
1103                                 rdct(nc, blk, MASK_VAL, up, uvstride, q1);
1104 
1105                                 // decode the 8x8-pixel Cr block (even
1106                                 // columns of the 16x8-pixel macroblock)
1107                                 nc = huffparse(comp_[2], blk, dummy, MASK_REF,
1108                                                1);
1109                                 rdct(nc, blk, MASK_VAL, vp, uvstride, q1);
1110 
1111                                 // line doubling
1112                                 if (type == JPEG_SINGLE_FIELD) {
1113                                     u_char* tu = up;
1114                                     u_char* tv = vp;
1115                                     for (int i=0; i<8; i++) {
1116                                         memcpy(tu + owidth_ / 2, tu, 8);
1117                                         tu += owidth_;
1118                                         memcpy(tv + owidth_ / 2, tv, 8);
1119                                         tv += owidth_;
1120                                     }
1121                                 }
1122                         } else {
1123                                 (void)huffskip(comp_[1]);
1124                                 (void)huffskip(comp_[2]);
1125                         }
1126 
1127                         if (dontskip) {
1128                                 marks[0] = mark;
1129                                 marks[1] = mark;
1130                                 if (type == JPEG_SINGLE_FIELD) {
1131                                         marks[markstride] = mark;
1132                                         marks[markstride+1] = mark;
1133                                 }
1134                                 
1135                                 // we've decoded 4 8x8-pixel blocks:
1136                                 // 2 Y, 1 U, and 1 V
1137                                 ndblk_ += 4;
1138                         }
1139                         marks += 2;
1140                         yp += 16;
1141                         up += 8;
1142                         vp += 8;
1143 
1144                 }
1145                 if (!ycrop) {
1146                         marks += m.markrskip;
1147                         yp += m.yrskip;
1148                         up += m.uvrskip;
1149                         vp += m.uvrskip;
1150                         cache += m.markrskip * NCC;
1151                         /*
1152                          * We're at the end of the current line.
1153                          * Back up to the beggining, then skip down
1154                          * one row to the start of the next mcu.
1155                          */
1156                         yp -= owidth_;
1157                         up -= owidth_ / 2;
1158                         vp -= owidth_ / 2;
1159 
1160                         yp += 8 * ystride;
1161                         up += 8 * uvstride;
1162                         vp += 8 * uvstride;