Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

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