1 /* 2 * Small jpeg decoder library 3 * 4 * Copyright (c) 2006, Luc Saillard <luc (at) 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 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 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 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 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 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 306 int tinyjpeg_parse_SOS(struct jdec_private *priv, const unsigned char *stream) 307 { 308 return parse_SOS(priv, stream); 309 } 310 311 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 } 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 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 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 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 */ 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 */ 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 */ 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 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 } 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 } 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