JpegDecoder.inl
上传用户:sz83729876
上传日期:2013-03-07
资源大小:4140k
文件大小:11k
源码类别:

OpenGL

开发平台:

Windows_Unix

  1. //------------------------------------------------------------------------------
  2. // inlines-- moved from .h file for clarity
  3. //------------------------------------------------------------------------------
  4. // Logical rotate left operation.
  5. inline uint jpeg_decoder::rol(uint i, uchar j)
  6. {
  7. #ifdef SUPPORT_X86ASM
  8.   // Breaks the rules a bit.. return value is in eax.
  9.   _asm
  10.   {
  11.     Mov eax, i
  12.     Mov cl, j
  13.     rol eax, cl
  14.   }
  15. #else
  16.   return ((i << j) | (i >> (32 - j)));
  17. #endif
  18. }
  19. //------------------------------------------------------------------------------
  20. // Retrieve one character from the input stream.
  21. inline uint jpeg_decoder::get_char(void)
  22. {
  23.   // Any bytes remaining in buffer?
  24.   if (!in_buf_left)
  25.   {
  26.     // Try to get more bytes.
  27.     prep_in_buffer();
  28.     // Still nothing to get?
  29.     if (!in_buf_left)
  30.     {
  31.       // Padd the end of the stream with 0xFF 0xD9 (EOI marker)
  32.       // FIXME: Is there a better padding pattern to use?
  33.       int t = tem_flag;
  34.       tem_flag ^= 1;
  35.       if (t)
  36.         return (0xD9);
  37.       else
  38.         return (0xFF);
  39.     }
  40.   }
  41.   uint c = *Pin_buf_ofs++;
  42.   in_buf_left--;
  43.   return (c);
  44. }
  45. //------------------------------------------------------------------------------
  46. // Same as previus method, except can indicate if the character is
  47. // a "padd" character or not.
  48. inline uint jpeg_decoder::get_char(bool *Ppadding_flag)
  49. {
  50.   if (!in_buf_left)
  51.   {
  52.     prep_in_buffer();
  53.     if (!in_buf_left)
  54.     {
  55.       *Ppadding_flag = true;
  56.       int t = tem_flag;
  57.       tem_flag ^= 1;
  58.       if (t)
  59.         return (0xD9);
  60.       else
  61.         return (0xFF);
  62.     }
  63.   }
  64.   *Ppadding_flag = false;
  65.   uint c = *Pin_buf_ofs++;
  66.   in_buf_left--;
  67.   return (c);
  68. }
  69. //------------------------------------------------------------------------------
  70. // Inserts a previously retrieved character back into the input buffer.
  71. inline void jpeg_decoder::stuff_char(uchar q)
  72. {
  73.   *(--Pin_buf_ofs) = q;
  74.   in_buf_left++;
  75. }
  76. //------------------------------------------------------------------------------
  77. // Retrieves one character from the input stream, but does
  78. // not read past markers. Will continue to return 0xFF when a
  79. // marker is encountered.
  80. // FIXME: Bad name?
  81. inline uchar jpeg_decoder::get_octet(void)
  82. {
  83.   bool padding_flag;
  84.   int c = get_char(&padding_flag);
  85.   if (c == 0xFF)
  86.   {
  87.     if (padding_flag)
  88.       return (0xFF);
  89.     c = get_char(&padding_flag);
  90.     if (padding_flag)
  91.     {
  92.       stuff_char(0xFF);
  93.       return (0xFF);
  94.     }
  95.     if (c == 0x00)
  96.       return (0xFF);
  97.     else
  98.     {
  99.       stuff_char(c);
  100.       stuff_char(0xFF);
  101.       return (0xFF);
  102.     }
  103.   }
  104.   return (c);
  105. }
  106. //------------------------------------------------------------------------------
  107. // Retrieves a variable number of bits from the input stream.
  108. // Does not recognize markers.
  109. inline uint jpeg_decoder::get_bits_1(int num_bits)
  110. {
  111.   uint i;
  112.   i = (bit_buf >> (16 - num_bits)) & ((1 << num_bits) - 1);
  113.   if ((bits_left -= num_bits) <= 0)
  114.   {
  115.     bit_buf = rol(bit_buf, num_bits += bits_left);
  116.     uint c1 = get_char();
  117.     uint c2 = get_char();
  118.     bit_buf = (bit_buf & 0xFFFF) | (((ulong)c1) << 24) | (((ulong)c2) << 16);
  119.     bit_buf = rol(bit_buf, -bits_left);
  120.     bits_left += 16;
  121.   }
  122.   else
  123.     bit_buf = rol(bit_buf, num_bits);
  124.   return i;
  125. }
  126. //------------------------------------------------------------------------------
  127. // Retrieves a variable number of bits from the input stream.
  128. // Markers will not be read into the input bit buffer. Instead,
  129. // an infinite number of all 1's will be returned when a marker
  130. // is encountered.
  131. // FIXME: Is it better to return all 0's instead, like the older implementation?
  132. inline uint jpeg_decoder::get_bits_2(int numbits)
  133. {
  134.   uint i;
  135.   i = (bit_buf >> (16 - numbits)) & ((1 << numbits) - 1);
  136.   if ((bits_left -= numbits) <= 0)
  137.   {
  138.     bit_buf = rol(bit_buf, numbits += bits_left);
  139.     uint c1 = get_octet();
  140.     uint c2 = get_octet();
  141.     bit_buf = (bit_buf & 0xFFFF) | (((ulong)c1) << 24) | (((ulong)c2) << 16);
  142.     bit_buf = rol(bit_buf, -bits_left);
  143.     bits_left += 16;
  144.   }
  145.   else
  146.     bit_buf = rol(bit_buf, numbits);
  147.   return i;
  148. }
  149. //------------------------------------------------------------------------------
  150. // Decodes a Huffman encoded symbol.
  151. inline int jpeg_decoder::huff_decode(Phuff_tables_t Ph)
  152. {
  153.   int symbol;
  154.   // Check first 8-bits: do we have a complete symbol?
  155.   if ((symbol = Ph->look_up[(bit_buf >> 8) & 0xFF]) < 0)
  156.   {
  157.     // Decode more bits, use a tree traversal to find symbol.
  158.     get_bits_2(8);
  159.     do
  160.     {
  161.       symbol = Ph->tree[~symbol + (1 - get_bits_2(1))];
  162.     } while (symbol < 0);
  163.   }
  164.   else
  165.     get_bits_2(Ph->code_size[symbol]);
  166.   return symbol;
  167. }
  168. //------------------------------------------------------------------------------
  169. // Tables and macro used to fully decode the DPCM differences.
  170. // (Note: In x86 asm this can be done without using tables.)
  171. const int extend_test[16] =   /* entry n is 2**(n-1) */
  172.   { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
  173.     0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 };
  174. const int extend_offset[16] = /* entry n is (-1 << n) + 1 */
  175.   { 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1,
  176.     ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1,
  177.     ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1,
  178.     ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1 };
  179. // used by huff_extend()
  180. const int extend_mask[] =
  181. {
  182.   0,
  183.   (1<<0), (1<<1), (1<<2), (1<<3),
  184.   (1<<4), (1<<5), (1<<6), (1<<7),
  185.   (1<<8), (1<<9), (1<<10), (1<<11),
  186.   (1<<12), (1<<13), (1<<14), (1<<15),
  187.   (1<<16),
  188. };
  189. #define HUFF_EXTEND_TBL(x,s) ((x) < extend_test[s] ? (x) + extend_offset[s] : (x))
  190. #ifdef SUPPORT_X86ASM
  191. // Use the inline ASM version instead to prevent jump misprediction issues
  192.   #define HUFF_EXTEND(x,s) huff_extend(x, s)
  193.   #define HUFF_EXTEND_P(x,s) Pd->huff_extend(x, s)
  194. #else
  195.   #define HUFF_EXTEND(x,s) HUFF_EXTEND_TBL(x,s)
  196.   #define HUFF_EXTEND_P(x,s) HUFF_EXTEND_TBL(x,s)
  197. #endif
  198. //------------------------------------------------------------------------------
  199. #ifdef SUPPORT_X86ASM
  200. // This code converts the raw unsigned coefficient bits
  201. // read from the data stream to the proper signed range.
  202. // There are many ways of doing this, see the HUFF_EXTEND_TBL
  203. // macro for an alternative way.
  204. // It purposelly avoids any decision making that requires jumping.
  205. inline uint jpeg_decoder::huff_extend(uint i, int c)
  206. {
  207.   _asm
  208.   {
  209.     mov ecx, c
  210.     mov eax, i
  211.     cmp eax, [ecx*4+extend_mask]
  212.     sbb edx, edx
  213.     shl edx, cl
  214.     adc eax, edx
  215.   }
  216. }
  217. #endif
  218. //------------------------------------------------------------------------------
  219. // Clamps a value between 0-255.
  220. inline uchar jpeg_decoder::clamp(int i)
  221. {
  222.   if (i & 0xFFFFFF00)
  223.     i = (((~i) >> 31) & 0xFF);
  224.   return (i);
  225. }
  226. //------------------------------------------------------------------------------
  227. #ifdef SUPPORT_MMX
  228. //------------------------------------------------------------------------------
  229. inline uint jpeg_decoder::get_high_byte_mmx(void)
  230. {
  231.   _asm
  232.   {
  233.     movq mm1, mm0
  234.     psrlq mm1, 56
  235.     movd eax, mm1
  236.   }
  237. }
  238. //------------------------------------------------------------------------------
  239. inline uint jpeg_decoder::get_high_word_mmx(void)
  240. {
  241.   _asm
  242.   {
  243.     movq mm1, mm0
  244.     psrlq mm1, 48
  245.     movd eax, mm1
  246.   }
  247. }
  248. //------------------------------------------------------------------------------
  249. inline void jpeg_decoder::get_bits_2_mmx_init(void)
  250. {
  251.   assert(!mmx_active);
  252.   mmx_active = true;
  253.   _asm
  254.   {
  255.     mov esi, this
  256.     movq mm0, [esi].bit_buf
  257.     movq mm1, [esi].saved_mm1
  258.   }
  259. }
  260. //------------------------------------------------------------------------------
  261. inline void jpeg_decoder::get_bits_2_mmx_deinit(void)
  262. {
  263.   assert(mmx_active);
  264.   mmx_active = false;
  265.   _asm
  266.   {
  267.     mov esi, this
  268.     movq [esi].bit_buf, mm0
  269.     movq [esi].saved_mm1, mm1
  270.     emms
  271.   }
  272. }
  273. //------------------------------------------------------------------------------
  274. static __int64 cmp_mask = 0xFFFFFFFFFFFFFFFF;
  275. static __int64 zero = 0;
  276. //------------------------------------------------------------------------------
  277. //FIXME: This function doesn't compile right with the Intel Compiler in Release builds.
  278. //Something to do with funciton inlining.
  279. inline uint jpeg_decoder::get_bits_2_mmx(int numbits)
  280. {
  281.   _asm
  282.   {
  283.     // is the "mov esi, this" really necessary?
  284.     // this is safe but it's probably already "this" anyway
  285.     mov esi, this
  286.     mov ecx, numbits
  287.     mov edx, 64
  288.     movd mm3, ecx
  289.     sub edx, ecx
  290.     movq mm1, mm0
  291.     movd mm2, edx
  292.     sub [esi].bits_left, ecx
  293.     psrlq mm1, mm2
  294.     Jg gb2_done
  295. //-----------------------------
  296.     add ecx, [esi].bits_left
  297.     cmp [esi].in_buf_left, 12
  298.     movd mm4, ecx
  299.     mov edi, [esi].Pin_buf_ofs
  300.     psllq mm0, mm4
  301.     jb gb2_slowload
  302. //-----------------------------
  303. // FIXME: Pair better!
  304.     mov eax, [edi]
  305.     mov ebx, [edi+4]
  306. // FIXME: Is there a better way to do this other than using bswap?
  307.     bswap eax
  308.     bswap ebx
  309.     movd mm4, eax
  310.     movd mm3, ebx
  311.     psllq mm4, 32
  312.     add [esi].Pin_buf_ofs, 6
  313.     por mm3, mm4
  314.     mov ecx, [esi].bits_left
  315.     psrlq mm3, 16
  316.     neg ecx
  317.     movq mm4, mm3
  318.     sub [esi].in_buf_left, 6
  319.     pcmpeqb mm4, cmp_mask
  320.     por mm0, mm3
  321.     pcmpeqd mm4, zero
  322.     movd mm3, ecx
  323.     pxor mm4, cmp_mask
  324.     movd eax, mm1
  325.     psrlq mm4, 1
  326.     add [esi].bits_left, 48
  327.     movd ebx, mm4
  328.     psllq mm0, mm3
  329.     test ebx, ebx
  330.     jz gb2_return
  331. //-----------------------------
  332.     psrlq mm0, mm3
  333.     sub [esi].bits_left, 48
  334.     sub [esi].Pin_buf_ofs, 6
  335.     add [esi].in_buf_left, 6
  336. gb2_slowload:
  337.     psrlq mm0, 48
  338.   }
  339.   for (int i = 0; i < 6; i++)
  340.   {
  341.     uint c = get_octet();
  342.     _asm
  343.     {
  344.       movd mm3, c
  345.       psllq mm0, 8
  346.       por mm0, mm3
  347.     }
  348.   }
  349.   _asm
  350.   {
  351.     mov esi, this
  352.     mov ecx, [esi].bits_left
  353.     neg ecx
  354.     movd mm3, ecx
  355.     add [esi].bits_left, 48
  356. gb2_done:
  357.     movd eax, mm1
  358.     psllq mm0, mm3
  359.   }
  360. gb2_return:;
  361. }
  362. //------------------------------------------------------------------------------
  363. inline int jpeg_decoder::huff_decode_mmx(Phuff_tables_t Ph)
  364. {
  365.   int symbol;
  366.   //uint d = get_high_word_mmx();
  367.   uint d;
  368.   _asm
  369.   {
  370.     movq mm1, mm0
  371.     psrlq mm1, 48
  372.     movd eax, mm1
  373.     mov d, eax
  374.   }
  375.   // Check first 8-bits: do we have a complete symbol?
  376.   if ((symbol = Ph->look_up[(d >> 8) & 0xFF]) < 0)
  377.   {
  378.     uint ofs = 7;
  379.     d = ~d; // invert d here so we don't have to do it inside the loop
  380.     do
  381.     {
  382.       symbol = Ph->tree[~symbol + ((d >> ofs) & 1)];
  383.       ofs--;
  384.     } while (symbol < 0);
  385.     // Decode more bits, use a tree traversal to find symbol.
  386.     get_bits_2_mmx(8 + (7 - ofs));
  387.   }
  388.   else
  389.     get_bits_2_mmx(Ph->code_size[symbol]);
  390.   return symbol;
  391. }
  392. //------------------------------------------------------------------------------
  393. #endif
  394. //------------------------------------------------------------------------------