1 /*
2 * Small jpeg decoder library
3 *
4 * Copyright (c) 2006, Luc Saillard <luc@saillard.org>
5 * Copyright (c) 2012 Intel Corporation.
6 * All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 *
13 * - Redistributions in binary form must reproduce the above copyright notice,
14 * this list of conditions and the following disclaimer in the documentation
15 * and/or other materials provided with the distribution.
16 *
17 * - Neither the name of the author nor the names of its contributors may be
18 * used to endorse or promote products derived from this software without
19 * specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 *
33 */
34
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <stdint.h>
39 #include <errno.h>
40
41 #include "tinyjpeg.h"
42 #include "tinyjpeg-internal.h"
43
44 // for libva
45 #include <unistd.h>
46 #include <sys/types.h>
47 #include <sys/stat.h>
48 #include <fcntl.h>
49 #include <assert.h>
50 #include <va/va.h>
51 #include <va/va_dec_jpeg.h>
52 #include "va_display.h"
53
54
55 #define cY 0
56 #define cCb 1
57 #define cCr 2
58
59 #define BLACK_Y 0
60 #define BLACK_U 127
61 #define BLACK_V 127
62
63 #ifndef MIN
64 #define MIN(a, b) ((a) < (b) ? (a) : (b))
65 #endif
66 #ifndef MAX
67 #define MAX(a, b) ((a) > (b) ? (a) : (b))
68 #endif
69 #define ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0]))
70
71 #if DEBUG
72 #define trace(fmt, args...) do { \
73 fprintf(stderr, fmt, ## args); \
74 fflush(stderr); \
75 } while(0)
76 #else
77 #define trace(fmt, args...) do { } while (0)
78 #endif
79 #define error(fmt, args...) do { \
80 snprintf(error_string, sizeof(error_string), fmt, ## args); \
81 return -1; \
82 } while(0)
83 /* The variables for different image scans */
84 static int scan_num=0;
85 static int next_image_found=0;
86 /* Global variable to return the last error found while deconding */
87 static char error_string[256];
88 static VAHuffmanTableBufferJPEGBaseline default_huffman_table_param={
89 huffman_table:
90 {
91 // lumiance component
92 {
93 num_dc_codes:{0,1,5,1,1,1,1,1,1,0,0,0}, // 12 bits is ok for baseline profile
94 dc_values:{0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b},
95 num_ac_codes:{0,2,1,3,3,2,4,3,5,5,4,4,0,0,1,125},
96 ac_values:{
97 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
98 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
99 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
100 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
101 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
102 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
103 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
104 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
105 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
106 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
107 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
108 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
109 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
110 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
111 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
112 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
113 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
114 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
115 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
116 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
117 0xf9, 0xfa
118 },/*,0xonly,0xthe,0xfirst,0x162,0xbytes,0xare,0xavailable,0x*/
119 },
120 // chrom component
121 {
122 num_dc_codes:{0,3,1,1,1,1,1,1,1,1,1,0}, // 12 bits is ok for baseline profile
123 dc_values:{0,1,2,3,4,5,6,7,8,9,0xa,0xb},
124 num_ac_codes:{0,2,1,2,4,4,3,4,7,5,4,4,0,1,2,119},
125 ac_values:{
126 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
127 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
128 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
129 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
130 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
131 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
132 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
133 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
134 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
135 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
136 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
137 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
138 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
139 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
140 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
141 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
142 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
143 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
144 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
145 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
146 0xf9, 0xfa
147 },/*,0xonly,0xthe,0xfirst,0x162,0xbytes,0xare,0xavailable,0x*/
148 },
149 }
150 };
151
152 #define be16_to_cpu(x) (((x)[0]<<8)|(x)[1])
153
154
build_default_huffman_tables(struct jdec_private * priv)155 static int build_default_huffman_tables(struct jdec_private *priv)
156 {
157 int i = 0;
158 if (priv->default_huffman_table_initialized)
159 return 0;
160
161 for (i = 0; i < 4; i++) {
162 priv->HTDC_valid[i] = 1;
163 memcpy(priv->HTDC[i].bits, default_huffman_table_param.huffman_table[i].num_dc_codes, 16);
164 memcpy(priv->HTDC[i].values, default_huffman_table_param.huffman_table[i].dc_values, 16);
165 priv->HTAC_valid[i] = 1;
166 memcpy(priv->HTAC[i].bits, default_huffman_table_param.huffman_table[i].num_ac_codes, 16);
167 memcpy(priv->HTAC[i].values, default_huffman_table_param.huffman_table[i].ac_values, 256);
168 }
169 priv->default_huffman_table_initialized = 1;
170 return 0;
171 }
172
173
print_SOF(const unsigned char * stream)174 static void print_SOF(const unsigned char *stream)
175 {
176 int width, height, nr_components, precision;
177 #if DEBUG
178 const char *nr_components_to_string[] = {
179 "????",
180 "Grayscale",
181 "????",
182 "YCbCr",
183 "CYMK"
184 };
185 #endif
186
187 precision = stream[2];
188 height = be16_to_cpu(stream+3);
189 width = be16_to_cpu(stream+5);
190 nr_components = stream[7];
191
192 trace("> SOF marker\n");
193 trace("Size:%dx%d nr_components:%d (%s) precision:%d\n",
194 width, height,
195 nr_components, nr_components_to_string[nr_components],
196 precision);
197 }
198
parse_DQT(struct jdec_private * priv,const unsigned char * stream)199 static int parse_DQT(struct jdec_private *priv, const unsigned char *stream)
200 {
201 int qi;
202 const unsigned char *dqt_block_end;
203
204 trace("> DQT marker\n");
205 dqt_block_end = stream + be16_to_cpu(stream);
206 stream += 2; /* Skip length */
207
208 while (stream < dqt_block_end)
209 {
210 qi = *stream++;
211 #if SANITY_CHECK
212 if (qi>>4)
213 error("16 bits quantization table is not supported\n");
214 if (qi>4)
215 error("No more 4 quantization table is supported (got %d)\n", qi);
216 #endif
217 memcpy(priv->Q_tables[qi&0x0F], stream, 64);
218 priv->Q_tables_valid[qi & 0x0f] = 1;
219 stream += 64;
220 }
221 trace("< DQT marker\n");
222 return 0;
223 }
224
parse_SOF(struct jdec_private * priv,const unsigned char * stream)225 static int parse_SOF(struct jdec_private *priv, const unsigned char *stream)
226 {
227 int i, width, height, nr_components, cid, sampling_factor;
228 unsigned char Q_table;
229 struct component *c;
230
231 trace("> SOF marker\n");
232 print_SOF(stream);
233
234 height = be16_to_cpu(stream+3);
235 width = be16_to_cpu(stream+5);
236 nr_components = stream[7];
237 priv->nf_components = nr_components;
238 #if SANITY_CHECK
239 if (stream[2] != 8)
240 error("Precision other than 8 is not supported\n");
241 if (width>JPEG_MAX_WIDTH || height>JPEG_MAX_HEIGHT)
242 printf("WARNING:Width and Height (%dx%d) seems suspicious\n", width, height);
243 if (nr_components != 3)
244 printf("ERROR:We only support YUV images\n");
245 if (height%16)
246 printf("WARNING:Height need to be a multiple of 16 (current height is %d)\n", height);
247 if (width%16)
248 printf("WARNING:Width need to be a multiple of 16 (current Width is %d)\n", width);
249 #endif
250 stream += 8;
251 for (i=0; i<nr_components; i++) {
252 cid = *stream++;
253 sampling_factor = *stream++;
254 Q_table = *stream++;
255 c = &priv->component_infos[i];
256 c->cid = cid;
257 if (Q_table >= COMPONENTS)
258 error("Bad Quantization table index (got %d, max allowed %d)\n", Q_table, COMPONENTS-1);
259 c->Vfactor = sampling_factor&0xf;
260 c->Hfactor = sampling_factor>>4;
261 c->quant_table_index = Q_table;
262 trace("Component:%d factor:%dx%d Quantization table:%d\n",
263 cid, c->Hfactor, c->Vfactor, Q_table );
264
265 }
266 priv->width[scan_num] = width;
267 priv->height[scan_num] = height;
268
269 trace("< SOF marker\n");
270
271 return 0;
272 }
273
parse_SOS(struct jdec_private * priv,const unsigned char * stream)274 static int parse_SOS(struct jdec_private *priv, const unsigned char *stream)
275 {
276 unsigned int i, cid, table;
277 unsigned int nr_components = stream[2];
278
279 trace("> SOS marker\n");
280
281 priv->cur_sos.nr_components= nr_components;
282
283 stream += 3;
284 for (i=0;i<nr_components;i++) {
285 cid = *stream++;
286 table = *stream++;
287 priv->cur_sos.components[i].component_id = cid;
288 priv->cur_sos.components[i].dc_selector = ((table>>4)&0x0F);
289 priv->cur_sos.components[i].ac_selector = (table&0x0F);
290 #if SANITY_CHECK
291 if ((table&0xf)>=4)
292 error("We do not support more than 2 AC Huffman table\n");
293 if ((table>>4)>=4)
294 error("We do not support more than 2 DC Huffman table\n");
295 if (cid != priv->component_infos[i].cid)
296 error("SOS cid order (%d:%d) isn't compatible with the SOF marker (%d:%d)\n",
297 i, cid, i, priv->component_infos[i].cid);
298 trace("ComponentId:%d tableAC:%d tableDC:%d\n", cid, table&0xf, table>>4);
299 #endif
300 }
301 priv->stream = stream+3;
302 trace("< SOS marker\n");
303 return 0;
304 }
305
tinyjpeg_parse_SOS(struct jdec_private * priv,const unsigned char * stream)306 int tinyjpeg_parse_SOS(struct jdec_private *priv, const unsigned char *stream)
307 {
308 return parse_SOS(priv, stream);
309 }
310
311
parse_DHT(struct jdec_private * priv,const unsigned char * stream)312 static int parse_DHT(struct jdec_private *priv, const unsigned char *stream)
313 {
314 unsigned int count, i;
315 int length, index;
316 unsigned char Tc, Th;
317
318 length = be16_to_cpu(stream) - 2;
319 stream += 2; /* Skip length */
320
321 trace("> DHT marker (length=%d)\n", length);
322
323 while (length>0) {
324 index = *stream++;
325
326 Tc = index & 0xf0; // it is not important to <<4
327 Th = index & 0x0f;
328 if (Tc) {
329 memcpy(priv->HTAC[index & 0xf].bits, stream, 16);
330 }
331 else {
332 memcpy(priv->HTDC[index & 0xf].bits, stream, 16);
333 }
334
335 count = 0;
336 for (i=0; i<16; i++) {
337 count += *stream++;
338 }
339
340 #if SANITY_CHECK
341 if (count >= HUFFMAN_BITS_SIZE)
342 error("No more than %d bytes is allowed to describe a huffman table", HUFFMAN_BITS_SIZE);
343 if ( (index &0xf) >= HUFFMAN_TABLES)
344 error("No more than %d Huffman tables is supported (got %d)\n", HUFFMAN_TABLES, index&0xf);
345 trace("Huffman table %s[%d] length=%d\n", (index&0xf0)?"AC":"DC", index&0xf, count);
346 #endif
347
348 if (Tc) {
349 memcpy(priv->HTAC[index & 0xf].values, stream, count);
350 priv->HTAC_valid[index & 0xf] = 1;
351 }
352 else {
353 memcpy(priv->HTDC[index & 0xf].values, stream, count);
354 priv->HTDC_valid[index & 0xf] = 1;
355 }
356
357 length -= 1;
358 length -= 16;
359 length -= count;
360 stream += count;
361 }
362 trace("< DHT marker\n");
363 return 0;
364 }
parse_DRI(struct jdec_private * priv,const unsigned char * stream)365 static int parse_DRI(struct jdec_private *priv, const unsigned char *stream)
366 {
367 unsigned int length;
368
369 trace("> DRI marker\n");
370
371 length = be16_to_cpu(stream);
372
373 #if SANITY_CHECK
374 if (length != 4)
375 error("Length of DRI marker need to be 4\n");
376 #endif
377
378 priv->restart_interval = be16_to_cpu(stream+2);
379
380 #if DEBUG
381 trace("Restart interval = %d\n", priv->restart_interval);
382 #endif
383
384 trace("< DRI marker\n");
385
386 return 0;
387 }
388
findEOI(struct jdec_private * priv,const unsigned char * stream)389 static int findEOI(struct jdec_private *priv,const unsigned char *stream)
390 {
391 while (!(*stream == 0xff && *(stream+1) == 0xd9 )&& stream<=priv->stream_end) //searching for the end of image marker
392 {
393 stream++;
394 continue;
395 }
396 priv->stream_scan=stream;
397 return 0;
398 }
399
findSOI(struct jdec_private * priv,const unsigned char * stream)400 static int findSOI(struct jdec_private *priv,const unsigned char *stream)
401 {
402 while (!(*stream == 0xff && *(stream+1) == 0xd8 ) ) //searching for the start of image marker
403 {
404 if(stream<=priv->stream_end)
405 {
406 stream++;
407 continue;
408 }
409 else
410 return 0; // No more images in the file.
411 }
412 priv->stream=stream+2;
413 return 1;
414 }
415
parse_JFIF(struct jdec_private * priv,const unsigned char * stream)416 static int parse_JFIF(struct jdec_private *priv, const unsigned char *stream)
417 {
418 int chuck_len;
419 int marker;
420 int sos_marker_found = 0;
421 int dht_marker_found = 0;
422 int dqt_marker_found = 0;
423 const unsigned char *next_chunck;
424
425 next_image_found = findSOI(priv,stream);
426 stream=priv->stream;
427
428 while (!sos_marker_found && stream<=priv->stream_end)
429 {
430 while((*stream == 0xff))
431 stream++;
432
433 marker = *stream++;
434 chuck_len = be16_to_cpu(stream);
435 next_chunck = stream + chuck_len;
436 switch (marker)
437 {
438 case SOF:
439 if (parse_SOF(priv, stream) < 0)
440 return -1;
441 break;
442 case DQT:
443 if (parse_DQT(priv, stream) < 0)
444 return -1;
445 dqt_marker_found = 1;
446 break;
447 case SOS:
448 if (parse_SOS(priv, stream) < 0)
449 return -1;
450 sos_marker_found = 1;
451 break;
452 case DHT:
453 if (parse_DHT(priv, stream) < 0)
454 return -1;
455 dht_marker_found = 1;
456 break;
457 case DRI:
458 if (parse_DRI(priv, stream) < 0)
459 return -1;
460 break;
461 default:
462 trace("> Unknown marker %2.2x\n", marker);
463 break;
464 }
465
466 stream = next_chunck;
467 }
468
469 if(next_image_found){
470 if (!dht_marker_found) {
471 trace("No Huffman table loaded, using the default one\n");
472 build_default_huffman_tables(priv);
473 }
474 if (!dqt_marker_found) {
475 error("ERROR:No Quantization table loaded, using the default one\n");
476 }
477 }
478 #ifdef SANITY_CHECK
479 if ( (priv->component_infos[cY].Hfactor < priv->component_infos[cCb].Hfactor)
480 || (priv->component_infos[cY].Hfactor < priv->component_infos[cCr].Hfactor))
481 error("Horizontal sampling factor for Y should be greater than horitontal sampling factor for Cb or Cr\n");
482 if ( (priv->component_infos[cY].Vfactor < priv->component_infos[cCb].Vfactor)
483 || (priv->component_infos[cY].Vfactor < priv->component_infos[cCr].Vfactor))
484 error("Vertical sampling factor for Y should be greater than vertical sampling factor for Cb or Cr\n");
485 if ( (priv->component_infos[cCb].Hfactor!=1)
486 || (priv->component_infos[cCr].Hfactor!=1)
487 || (priv->component_infos[cCb].Vfactor!=1)
488 || (priv->component_infos[cCr].Vfactor!=1))
489 printf("ERROR:Sampling other than 1x1 for Cr and Cb is not supported");
490 #endif
491 findEOI(priv,stream);
492 return next_image_found;
493 }
494
495 /*******************************************************************************
496 *
497 * Functions exported of the library.
498 *
499 * Note: Some applications can access directly to internal pointer of the
500 * structure. It's is not recommended, but if you have many images to
501 * uncompress with the same parameters, some functions can be called to speedup
502 * the decoding.
503 *
504 ******************************************************************************/
505
506 /**
507 * Allocate a new tinyjpeg decoder object.
508 *
509 * Before calling any other functions, an object need to be called.
510 */
tinyjpeg_init(void)511 struct jdec_private *tinyjpeg_init(void)
512 {
513 struct jdec_private *priv;
514
515 priv = (struct jdec_private *)calloc(1, sizeof(struct jdec_private));
516 if (priv == NULL)
517 return NULL;
518 return priv;
519 }
520
521 /**
522 * Free a tinyjpeg object.
523 *
524 * No others function can be called after this one.
525 */
tinyjpeg_free(struct jdec_private * priv)526 void tinyjpeg_free(struct jdec_private *priv)
527 {
528 free(priv);
529 }
530
531 /**
532 * Initialize the tinyjpeg object and prepare the decoding of the stream.
533 *
534 * Check if the jpeg can be decoded with this jpeg decoder.
535 * Fill some table used for preprocessing.
536 */
tinyjpeg_parse_header(struct jdec_private * priv,const unsigned char * buf,unsigned int size)537 int tinyjpeg_parse_header(struct jdec_private *priv, const unsigned char *buf, unsigned int size)
538 {
539 int ret;
540
541 /* Identify the file */
542 if ((buf[0] != 0xFF) || (buf[1] != SOI))
543 error("Not a JPG file ?\n");
544
545 priv->stream_begin = buf;
546 priv->stream_length = size;
547 priv->stream_end = priv->stream_begin + priv->stream_length;
548
549 priv->stream = priv->stream_begin;
550 ret = parse_JFIF(priv, priv->stream);
551 return ret;
552 }
553
554
tinyjpeg_decode(struct jdec_private * priv)555 int tinyjpeg_decode(struct jdec_private *priv)
556 {
557 #define CHECK_VASTATUS(va_status,func) \
558 if (va_status != VA_STATUS_SUCCESS) { \
559 fprintf(stderr,"%s:%s (%d) failed,exit\n", __func__, func, __LINE__); \
560 exit(1); \
561 }
562
563 VAEntrypoint entrypoints[5];
564 int num_entrypoints,vld_entrypoint;
565 VAConfigAttrib attrib;
566 VAConfigID config_id;
567 VASurfaceID surface_id;
568 VAContextID context_id;
569 VABufferID pic_param_buf,iqmatrix_buf,huffmantable_buf,slice_param_buf,slice_data_buf;
570 int major_ver, minor_ver;
571 VADisplay va_dpy;
572 VAStatus va_status;
573 int max_h_factor, max_v_factor;
574 int putsurface=1;
575 unsigned int i, j;
576
577 int surface_type;
578 char *type;
579 int ChromaTypeIndex;
580
581 VASurfaceAttrib forcc;
582 forcc.type =VASurfaceAttribPixelFormat;
583 forcc.flags=VA_SURFACE_ATTRIB_SETTABLE;
584 forcc.value.type=VAGenericValueTypeInteger;
585
586
587 va_dpy = va_open_display();
588 va_status = vaInitialize(va_dpy, &major_ver, &minor_ver);
589 assert(va_status == VA_STATUS_SUCCESS);
590
591 va_status = vaQueryConfigEntrypoints(va_dpy, VAProfileJPEGBaseline, entrypoints,
592 &num_entrypoints);
593 CHECK_VASTATUS(va_status, "vaQueryConfigEntrypoints");
594
595 for (vld_entrypoint = 0; vld_entrypoint < num_entrypoints; vld_entrypoint++) {
596 if (entrypoints[vld_entrypoint] == VAEntrypointVLD)
597 break;
598 }
599 if (vld_entrypoint == num_entrypoints) {
600 /* not find VLD entry point */
601 assert(0);
602 }
603
604 /* Assuming finding VLD, find out the format for the render target */
605 attrib.type = VAConfigAttribRTFormat;
606 vaGetConfigAttributes(va_dpy, VAProfileJPEGBaseline, VAEntrypointVLD,
607 &attrib, 1);
608 if ((attrib.value & VA_RT_FORMAT_YUV420) == 0) {
609 /* not find desired YUV420 RT format */
610 assert(0);
611 }
612
613 va_status = vaCreateConfig(va_dpy, VAProfileJPEGBaseline, VAEntrypointVLD,
614 &attrib, 1,&config_id);
615 CHECK_VASTATUS(va_status, "vaQueryConfigEntrypoints");
616
617 while (next_image_found){
618 VAPictureParameterBufferJPEGBaseline pic_param;
619 memset(&pic_param, 0, sizeof(pic_param));
620 pic_param.picture_width = priv->width[scan_num];
621 pic_param.picture_height = priv->height[scan_num];
622 pic_param.num_components = priv->nf_components;
623
624
625 for (i=0; i<pic_param.num_components; i++) { // tinyjpeg support 3 components only, does it match va?
626 pic_param.components[i].component_id = priv->component_infos[i].cid;
627 pic_param.components[i].h_sampling_factor = priv->component_infos[i].Hfactor;
628 pic_param.components[i].v_sampling_factor = priv->component_infos[i].Vfactor;
629 pic_param.components[i].quantiser_table_selector = priv->component_infos[i].quant_table_index;
630 }
631 int h1, h2, h3, v1, v2, v3;
632 h1 = pic_param.components[0].h_sampling_factor;
633 h2 = pic_param.components[1].h_sampling_factor;
634 h3 = pic_param.components[2].h_sampling_factor;
635 v1 = pic_param.components[0].v_sampling_factor;
636 v2 = pic_param.components[1].v_sampling_factor;
637 v3 = pic_param.components[2].v_sampling_factor;
638
639 if (h1 == 2 && h2 == 1 && h3 == 1 &&
640 v1 == 2 && v2 == 1 && v3 == 1) {
641 //surface_type = VA_RT_FORMAT_IMC3;
642 surface_type = VA_RT_FORMAT_YUV420;
643 forcc.value.value.i = VA_FOURCC_IMC3;
644 ChromaTypeIndex = 1;
645 type = "VA_FOURCC_IMC3";
646 }
647 else if (h1 == 2 && h2 == 1 && h3 == 1 &&
648 v1 == 1 && v2 == 1 && v3 == 1) {
649 //surface_type = VA_RT_FORMAT_YUV422H;
650 surface_type = VA_RT_FORMAT_YUV422;
651 forcc.value.value.i = VA_FOURCC_422H;
652 ChromaTypeIndex = 2;
653 type = "VA_FOURCC_422H";
654 }
655 else if (h1 == 1 && h2 == 1 && h3 == 1 &&
656 v1 == 1 && v2 == 1 && v3 == 1) {
657 surface_type = VA_RT_FORMAT_YUV444;
658 forcc.value.value.i = VA_FOURCC_444P;
659 //forcc.value.value.i = VA_FOURCC_RGBP;
660 ChromaTypeIndex = 3;
661 type = "VA_FOURCC_444P";
662 }
663 else if (h1 == 4 && h2 == 1 && h3 == 1 &&
664 v1 == 1 && v2 == 1 && v3 == 1) {
665 surface_type = VA_RT_FORMAT_YUV411;
666 forcc.value.value.i = VA_FOURCC_411P;
667 ChromaTypeIndex = 4;
668 type = "VA_FOURCC_411P";
669 }
670 else if (h1 == 1 && h2 == 1 && h3 == 1 &&
671 v1 == 2 && v2 == 1 && v3 == 1) {
672 //surface_type = VA_RT_FORMAT_YUV422V;
673 surface_type = VA_RT_FORMAT_YUV422;
674 forcc.value.value.i = VA_FOURCC_422V;
675 ChromaTypeIndex = 5;
676 type = "VA_FOURCC_422V";
677 }
678 else if (h1 == 2 && h2 == 1 && h3 == 1 &&
679 v1 == 2 && v2 == 2 && v3 == 2) {
680 //surface_type = VA_RT_FORMAT_YUV422H;
681 surface_type = VA_RT_FORMAT_YUV422;
682 forcc.value.value.i = VA_FOURCC_422H;
683 ChromaTypeIndex = 6;
684 type = "VA_FOURCC_422H";
685 }
686 else if (h2 == 2 && h2 == 2 && h3 == 2 &&
687 v1 == 2 && v2 == 1 && v3 == 1) {
688 //surface_type = VA_RT_FORMAT_YUV422V;
689 surface_type = VA_RT_FORMAT_YUV422;
690 forcc.value.value.i = VA_FOURCC_422V;
691 ChromaTypeIndex = 7;
692 type = "VA_FOURCC_422V";
693 }
694 else
695 {
696 surface_type = VA_RT_FORMAT_YUV400;
697 forcc.value.value.i = VA_FOURCC('Y','8','0','0');
698 ChromaTypeIndex = 0;
699 type = "Format_400P";
700 }
701
702 va_status = vaCreateSurfaces(va_dpy,surface_type,
703 priv->width[scan_num],priv->height[scan_num], //alignment?
704 &surface_id, 1, &forcc, 1);
705 CHECK_VASTATUS(va_status, "vaCreateSurfaces");
706
707 /* Create a context for this decode pipe */
708 va_status = vaCreateContext(va_dpy, config_id,
709 priv->width[scan_num], priv->height[scan_num], // alignment?
710 VA_PROGRESSIVE,
711 &surface_id,
712 1,
713 &context_id);
714 CHECK_VASTATUS(va_status, "vaCreateContext");
715
716 va_status = vaCreateBuffer(va_dpy, context_id,
717 VAPictureParameterBufferType, // VAPictureParameterBufferJPEGBaseline?
718 sizeof(VAPictureParameterBufferJPEGBaseline),
719 1, &pic_param,
720 &pic_param_buf);
721 CHECK_VASTATUS(va_status, "vaCreateBuffer");
722
723 VAIQMatrixBufferJPEGBaseline iq_matrix;
724 const unsigned int num_quant_tables =
725 MIN(COMPONENTS, ARRAY_ELEMS(iq_matrix.load_quantiser_table));
726 // todo, only mask it if non-default quant matrix is used. do we need build default quant matrix?
727 memset(&iq_matrix, 0, sizeof(VAIQMatrixBufferJPEGBaseline));
728 for (i = 0; i < num_quant_tables; i++) {
729 if (!priv->Q_tables_valid[i])
730 continue;
731 iq_matrix.load_quantiser_table[i] = 1;
732 for (j = 0; j < 64; j++)
733 iq_matrix.quantiser_table[i][j] = priv->Q_tables[i][j];
734 }
735 va_status = vaCreateBuffer(va_dpy, context_id,
736 VAIQMatrixBufferType, // VAIQMatrixBufferJPEGBaseline?
737 sizeof(VAIQMatrixBufferJPEGBaseline),
738 1, &iq_matrix,
739 &iqmatrix_buf );
740 CHECK_VASTATUS(va_status, "vaCreateBuffer");
741
742 VAHuffmanTableBufferJPEGBaseline huffman_table;
743 const unsigned int num_huffman_tables =
744 MIN(COMPONENTS, ARRAY_ELEMS(huffman_table.load_huffman_table));
745 memset(&huffman_table, 0, sizeof(VAHuffmanTableBufferJPEGBaseline));
746 assert(sizeof(huffman_table.huffman_table[0].num_dc_codes) ==
747 sizeof(priv->HTDC[0].bits));
748 assert(sizeof(huffman_table.huffman_table[0].dc_values[0]) ==
749 sizeof(priv->HTDC[0].values[0]));
750 for (i = 0; i < num_huffman_tables; i++) {
751 if (!priv->HTDC_valid[i] || !priv->HTAC_valid[i])
752 continue;
753 huffman_table.load_huffman_table[i] = 1;
754 memcpy(huffman_table.huffman_table[i].num_dc_codes, priv->HTDC[i].bits,
755 sizeof(huffman_table.huffman_table[i].num_dc_codes));
756 memcpy(huffman_table.huffman_table[i].dc_values, priv->HTDC[i].values,
757 sizeof(huffman_table.huffman_table[i].dc_values));
758 memcpy(huffman_table.huffman_table[i].num_ac_codes, priv->HTAC[i].bits,
759 sizeof(huffman_table.huffman_table[i].num_ac_codes));
760 memcpy(huffman_table.huffman_table[i].ac_values, priv->HTAC[i].values,
761 sizeof(huffman_table.huffman_table[i].ac_values));
762 memset(huffman_table.huffman_table[i].pad, 0,
763 sizeof(huffman_table.huffman_table[i].pad));
764 }
765 va_status = vaCreateBuffer(va_dpy, context_id,
766 VAHuffmanTableBufferType, // VAHuffmanTableBufferJPEGBaseline?
767 sizeof(VAHuffmanTableBufferJPEGBaseline),
768 1, &huffman_table,
769 &huffmantable_buf );
770 CHECK_VASTATUS(va_status, "vaCreateBuffer");
771
772 // one slice for whole image?
773 max_h_factor = priv->component_infos[0].Hfactor;
774 max_v_factor = priv->component_infos[0].Vfactor;
775 static VASliceParameterBufferJPEGBaseline slice_param;
776 slice_param.slice_data_size = (priv->stream_scan - priv->stream);
777 slice_param.slice_data_offset = 0;
778 slice_param.slice_data_flag = VA_SLICE_DATA_FLAG_ALL;
779 slice_param.slice_horizontal_position = 0;
780 slice_param.slice_vertical_position = 0;
781 slice_param.num_components = priv->cur_sos.nr_components;
782 for (i = 0; i < slice_param.num_components; i++) {
783 slice_param.components[i].component_selector = priv->cur_sos.components[i].component_id; /* FIXME: set to values specified in SOS */
784 slice_param.components[i].dc_table_selector = priv->cur_sos.components[i].dc_selector; /* FIXME: set to values specified in SOS */
785 slice_param.components[i].ac_table_selector = priv->cur_sos.components[i].ac_selector; /* FIXME: set to values specified in SOS */
786 }
787 slice_param.restart_interval = priv->restart_interval;
788 slice_param.num_mcus = ((priv->width[scan_num]+max_h_factor*8-1)/(max_h_factor*8))*
789 ((priv->height[scan_num]+max_v_factor*8-1)/(max_v_factor*8)); // ?? 720/16?
790
791 va_status = vaCreateBuffer(va_dpy, context_id,
792 VASliceParameterBufferType, // VASliceParameterBufferJPEGBaseline?
793 sizeof(VASliceParameterBufferJPEGBaseline),
794 1,
795 &slice_param, &slice_param_buf);
796 CHECK_VASTATUS(va_status, "vaCreateBuffer");
797
798 va_status = vaCreateBuffer(va_dpy, context_id,
799 VASliceDataBufferType,
800 priv->stream_scan - priv->stream,
801 1,
802 (void*)priv->stream, // jpeg_clip,
803 &slice_data_buf);
804 CHECK_VASTATUS(va_status, "vaCreateBuffer");
805
806 va_status = vaBeginPicture(va_dpy, context_id, surface_id);
807 CHECK_VASTATUS(va_status, "vaBeginPicture");
808
809 va_status = vaRenderPicture(va_dpy,context_id, &pic_param_buf, 1);
810 CHECK_VASTATUS(va_status, "vaRenderPicture");
811
812 va_status = vaRenderPicture(va_dpy,context_id, &iqmatrix_buf, 1);
813 CHECK_VASTATUS(va_status, "vaRenderPicture");
814
815 va_status = vaRenderPicture(va_dpy,context_id, &huffmantable_buf, 1);
816 CHECK_VASTATUS(va_status, "vaRenderPicture");
817
818 va_status = vaRenderPicture(va_dpy,context_id, &slice_param_buf, 1);
819 CHECK_VASTATUS(va_status, "vaRenderPicture");
820
821 va_status = vaRenderPicture(va_dpy,context_id, &slice_data_buf, 1);
822 CHECK_VASTATUS(va_status, "vaRenderPicture");
823
824 va_status = vaEndPicture(va_dpy,context_id);
825 CHECK_VASTATUS(va_status, "vaEndPicture");
826
827 va_status = vaSyncSurface(va_dpy, surface_id);
828 CHECK_VASTATUS(va_status, "vaSyncSurface");
829
830 if (putsurface) {
831 VARectangle src_rect, dst_rect;
832
833 src_rect.x = 0;
834 src_rect.y = 0;
835 src_rect.width = priv->width[scan_num];
836 src_rect.height = priv->height[scan_num];
837 dst_rect = src_rect;
838
839 va_status = va_put_surface(va_dpy, surface_id, &src_rect, &dst_rect);
840 CHECK_VASTATUS(va_status, "vaPutSurface");
841 }
842 scan_num++;
843
844 vaDestroySurfaces(va_dpy,&surface_id,1);
845 vaDestroyConfig(va_dpy,config_id);
846 vaDestroyContext(va_dpy,context_id);
847
848 parse_JFIF(priv,priv->stream);
849 if(priv->width[scan_num] == 0 && priv->height[scan_num] == 0)
850 break;
851 }
852 // va_close_display(va_dpy);
853 vaTerminate(va_dpy);
854 printf("press any key to exit23\n");
855 getchar();
856 return 0;
857 }
tinyjpeg_get_errorstring(struct jdec_private * priv)858 const char *tinyjpeg_get_errorstring(struct jdec_private *priv)
859 {
860 /* FIXME: the error string must be store in the context */
861 priv = priv;
862 return error_string;
863 }
tinyjpeg_get_size(struct jdec_private * priv,unsigned int * width,unsigned int * height)864 void tinyjpeg_get_size(struct jdec_private *priv, unsigned int *width, unsigned int *height)
865 {
866 *width = priv->width[scan_num];
867 *height = priv->height[scan_num];
868 }
869
870
871