Path: blob/master/thirdparty/basis_universal/encoder/jpgd.cpp
9903 views
// jpgd.cpp - C++ class for JPEG decompression. Written by Richard Geldreich <[email protected]> between 1994-2020.1// Supports progressive and baseline sequential JPEG image files, and the most common chroma subsampling factors: Y, H1V1, H2V1, H1V2, and H2V2.2// Supports box and linear chroma upsampling.3//4// Released under two licenses. You are free to choose which license you want:5// License 1:6// Public Domain7//8// License 2:9// Licensed under the Apache License, Version 2.0 (the "License");10// you may not use this file except in compliance with the License.11// You may obtain a copy of the License at12//13// http://www.apache.org/licenses/LICENSE-2.014//15// Unless required by applicable law or agreed to in writing, software16// distributed under the License is distributed on an "AS IS" BASIS,17// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.18// See the License for the specific language governing permissions and19// limitations under the License.20//21// Alex Evans: Linear memory allocator (taken from jpge.h).22// v1.04, May. 19, 2012: Code tweaks to fix VS2008 static code analysis warnings23// v2.00, March 20, 2020: Fuzzed with zzuf and afl. Fixed several issues, converted most assert()'s to run-time checks. Added chroma upsampling. Removed freq. domain upsampling. gcc/clang warnings.24//2526#include "jpgd.h"27#include <string.h>28#include <algorithm>29#include <assert.h>3031#ifdef _MSC_VER32#pragma warning (disable : 4611) // warning C4611: interaction between '_setjmp' and C++ object destruction is non-portable33#endif3435#define JPGD_TRUE (1)36#define JPGD_FALSE (0)3738#define JPGD_MAX(a,b) (((a)>(b)) ? (a) : (b))39#define JPGD_MIN(a,b) (((a)<(b)) ? (a) : (b))4041namespace jpgd {4243static inline void* jpgd_malloc(size_t nSize) { return malloc(nSize); }44static inline void jpgd_free(void* p) { free(p); }4546// DCT coefficients are stored in this sequence.47static int g_ZAG[64] = { 0,1,8,16,9,2,3,10,17,24,32,25,18,11,4,5,12,19,26,33,40,48,41,34,27,20,13,6,7,14,21,28,35,42,49,56,57,50,43,36,29,22,15,23,30,37,44,51,58,59,52,45,38,31,39,46,53,60,61,54,47,55,62,63 };4849enum JPEG_MARKER50{51M_SOF0 = 0xC0, M_SOF1 = 0xC1, M_SOF2 = 0xC2, M_SOF3 = 0xC3, M_SOF5 = 0xC5, M_SOF6 = 0xC6, M_SOF7 = 0xC7, M_JPG = 0xC8,52M_SOF9 = 0xC9, M_SOF10 = 0xCA, M_SOF11 = 0xCB, M_SOF13 = 0xCD, M_SOF14 = 0xCE, M_SOF15 = 0xCF, M_DHT = 0xC4, M_DAC = 0xCC,53M_RST0 = 0xD0, M_RST1 = 0xD1, M_RST2 = 0xD2, M_RST3 = 0xD3, M_RST4 = 0xD4, M_RST5 = 0xD5, M_RST6 = 0xD6, M_RST7 = 0xD7,54M_SOI = 0xD8, M_EOI = 0xD9, M_SOS = 0xDA, M_DQT = 0xDB, M_DNL = 0xDC, M_DRI = 0xDD, M_DHP = 0xDE, M_EXP = 0xDF,55M_APP0 = 0xE0, M_APP15 = 0xEF, M_JPG0 = 0xF0, M_JPG13 = 0xFD, M_COM = 0xFE, M_TEM = 0x01, M_ERROR = 0x100, RST0 = 0xD056};5758enum JPEG_SUBSAMPLING { JPGD_GRAYSCALE = 0, JPGD_YH1V1, JPGD_YH2V1, JPGD_YH1V2, JPGD_YH2V2 };5960#define CONST_BITS 1361#define PASS1_BITS 262#define SCALEDONE ((int32)1)6364#define FIX_0_298631336 ((int32)2446) /* FIX(0.298631336) */65#define FIX_0_390180644 ((int32)3196) /* FIX(0.390180644) */66#define FIX_0_541196100 ((int32)4433) /* FIX(0.541196100) */67#define FIX_0_765366865 ((int32)6270) /* FIX(0.765366865) */68#define FIX_0_899976223 ((int32)7373) /* FIX(0.899976223) */69#define FIX_1_175875602 ((int32)9633) /* FIX(1.175875602) */70#define FIX_1_501321110 ((int32)12299) /* FIX(1.501321110) */71#define FIX_1_847759065 ((int32)15137) /* FIX(1.847759065) */72#define FIX_1_961570560 ((int32)16069) /* FIX(1.961570560) */73#define FIX_2_053119869 ((int32)16819) /* FIX(2.053119869) */74#define FIX_2_562915447 ((int32)20995) /* FIX(2.562915447) */75#define FIX_3_072711026 ((int32)25172) /* FIX(3.072711026) */7677#define DESCALE(x,n) (((x) + (SCALEDONE << ((n)-1))) >> (n))78#define DESCALE_ZEROSHIFT(x,n) (((x) + (128 << (n)) + (SCALEDONE << ((n)-1))) >> (n))7980#define MULTIPLY(var, cnst) ((var) * (cnst))8182#define CLAMP(i) ((static_cast<uint>(i) > 255) ? (((~i) >> 31) & 0xFF) : (i))8384static inline int left_shifti(int val, uint32_t bits)85{86return static_cast<int>(static_cast<uint32_t>(val) << bits);87}8889// Compiler creates a fast path 1D IDCT for X non-zero columns90template <int NONZERO_COLS>91struct Row92{93static void idct(int* pTemp, const jpgd_block_t* pSrc)94{95// ACCESS_COL() will be optimized at compile time to either an array access, or 0. Good compilers will then optimize out muls against 0.96#define ACCESS_COL(x) (((x) < NONZERO_COLS) ? (int)pSrc[x] : 0)9798const int z2 = ACCESS_COL(2), z3 = ACCESS_COL(6);99100const int z1 = MULTIPLY(z2 + z3, FIX_0_541196100);101const int tmp2 = z1 + MULTIPLY(z3, -FIX_1_847759065);102const int tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865);103104const int tmp0 = left_shifti(ACCESS_COL(0) + ACCESS_COL(4), CONST_BITS);105const int tmp1 = left_shifti(ACCESS_COL(0) - ACCESS_COL(4), CONST_BITS);106107const int tmp10 = tmp0 + tmp3, tmp13 = tmp0 - tmp3, tmp11 = tmp1 + tmp2, tmp12 = tmp1 - tmp2;108109const int atmp0 = ACCESS_COL(7), atmp1 = ACCESS_COL(5), atmp2 = ACCESS_COL(3), atmp3 = ACCESS_COL(1);110111const int bz1 = atmp0 + atmp3, bz2 = atmp1 + atmp2, bz3 = atmp0 + atmp2, bz4 = atmp1 + atmp3;112const int bz5 = MULTIPLY(bz3 + bz4, FIX_1_175875602);113114const int az1 = MULTIPLY(bz1, -FIX_0_899976223);115const int az2 = MULTIPLY(bz2, -FIX_2_562915447);116const int az3 = MULTIPLY(bz3, -FIX_1_961570560) + bz5;117const int az4 = MULTIPLY(bz4, -FIX_0_390180644) + bz5;118119const int btmp0 = MULTIPLY(atmp0, FIX_0_298631336) + az1 + az3;120const int btmp1 = MULTIPLY(atmp1, FIX_2_053119869) + az2 + az4;121const int btmp2 = MULTIPLY(atmp2, FIX_3_072711026) + az2 + az3;122const int btmp3 = MULTIPLY(atmp3, FIX_1_501321110) + az1 + az4;123124pTemp[0] = DESCALE(tmp10 + btmp3, CONST_BITS - PASS1_BITS);125pTemp[7] = DESCALE(tmp10 - btmp3, CONST_BITS - PASS1_BITS);126pTemp[1] = DESCALE(tmp11 + btmp2, CONST_BITS - PASS1_BITS);127pTemp[6] = DESCALE(tmp11 - btmp2, CONST_BITS - PASS1_BITS);128pTemp[2] = DESCALE(tmp12 + btmp1, CONST_BITS - PASS1_BITS);129pTemp[5] = DESCALE(tmp12 - btmp1, CONST_BITS - PASS1_BITS);130pTemp[3] = DESCALE(tmp13 + btmp0, CONST_BITS - PASS1_BITS);131pTemp[4] = DESCALE(tmp13 - btmp0, CONST_BITS - PASS1_BITS);132}133};134135template <>136struct Row<0>137{138static void idct(int* pTemp, const jpgd_block_t* pSrc)139{140(void)pTemp;141(void)pSrc;142}143};144145template <>146struct Row<1>147{148static void idct(int* pTemp, const jpgd_block_t* pSrc)149{150const int dcval = left_shifti(pSrc[0], PASS1_BITS);151152pTemp[0] = dcval;153pTemp[1] = dcval;154pTemp[2] = dcval;155pTemp[3] = dcval;156pTemp[4] = dcval;157pTemp[5] = dcval;158pTemp[6] = dcval;159pTemp[7] = dcval;160}161};162163// Compiler creates a fast path 1D IDCT for X non-zero rows164template <int NONZERO_ROWS>165struct Col166{167static void idct(uint8* pDst_ptr, const int* pTemp)168{169// ACCESS_ROW() will be optimized at compile time to either an array access, or 0.170#define ACCESS_ROW(x) (((x) < NONZERO_ROWS) ? pTemp[x * 8] : 0)171172const int z2 = ACCESS_ROW(2);173const int z3 = ACCESS_ROW(6);174175const int z1 = MULTIPLY(z2 + z3, FIX_0_541196100);176const int tmp2 = z1 + MULTIPLY(z3, -FIX_1_847759065);177const int tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865);178179const int tmp0 = left_shifti(ACCESS_ROW(0) + ACCESS_ROW(4), CONST_BITS);180const int tmp1 = left_shifti(ACCESS_ROW(0) - ACCESS_ROW(4), CONST_BITS);181182const int tmp10 = tmp0 + tmp3, tmp13 = tmp0 - tmp3, tmp11 = tmp1 + tmp2, tmp12 = tmp1 - tmp2;183184const int atmp0 = ACCESS_ROW(7), atmp1 = ACCESS_ROW(5), atmp2 = ACCESS_ROW(3), atmp3 = ACCESS_ROW(1);185186const int bz1 = atmp0 + atmp3, bz2 = atmp1 + atmp2, bz3 = atmp0 + atmp2, bz4 = atmp1 + atmp3;187const int bz5 = MULTIPLY(bz3 + bz4, FIX_1_175875602);188189const int az1 = MULTIPLY(bz1, -FIX_0_899976223);190const int az2 = MULTIPLY(bz2, -FIX_2_562915447);191const int az3 = MULTIPLY(bz3, -FIX_1_961570560) + bz5;192const int az4 = MULTIPLY(bz4, -FIX_0_390180644) + bz5;193194const int btmp0 = MULTIPLY(atmp0, FIX_0_298631336) + az1 + az3;195const int btmp1 = MULTIPLY(atmp1, FIX_2_053119869) + az2 + az4;196const int btmp2 = MULTIPLY(atmp2, FIX_3_072711026) + az2 + az3;197const int btmp3 = MULTIPLY(atmp3, FIX_1_501321110) + az1 + az4;198199int i = DESCALE_ZEROSHIFT(tmp10 + btmp3, CONST_BITS + PASS1_BITS + 3);200pDst_ptr[8 * 0] = (uint8)CLAMP(i);201202i = DESCALE_ZEROSHIFT(tmp10 - btmp3, CONST_BITS + PASS1_BITS + 3);203pDst_ptr[8 * 7] = (uint8)CLAMP(i);204205i = DESCALE_ZEROSHIFT(tmp11 + btmp2, CONST_BITS + PASS1_BITS + 3);206pDst_ptr[8 * 1] = (uint8)CLAMP(i);207208i = DESCALE_ZEROSHIFT(tmp11 - btmp2, CONST_BITS + PASS1_BITS + 3);209pDst_ptr[8 * 6] = (uint8)CLAMP(i);210211i = DESCALE_ZEROSHIFT(tmp12 + btmp1, CONST_BITS + PASS1_BITS + 3);212pDst_ptr[8 * 2] = (uint8)CLAMP(i);213214i = DESCALE_ZEROSHIFT(tmp12 - btmp1, CONST_BITS + PASS1_BITS + 3);215pDst_ptr[8 * 5] = (uint8)CLAMP(i);216217i = DESCALE_ZEROSHIFT(tmp13 + btmp0, CONST_BITS + PASS1_BITS + 3);218pDst_ptr[8 * 3] = (uint8)CLAMP(i);219220i = DESCALE_ZEROSHIFT(tmp13 - btmp0, CONST_BITS + PASS1_BITS + 3);221pDst_ptr[8 * 4] = (uint8)CLAMP(i);222}223};224225template <>226struct Col<1>227{228static void idct(uint8* pDst_ptr, const int* pTemp)229{230int dcval = DESCALE_ZEROSHIFT(pTemp[0], PASS1_BITS + 3);231const uint8 dcval_clamped = (uint8)CLAMP(dcval);232pDst_ptr[0 * 8] = dcval_clamped;233pDst_ptr[1 * 8] = dcval_clamped;234pDst_ptr[2 * 8] = dcval_clamped;235pDst_ptr[3 * 8] = dcval_clamped;236pDst_ptr[4 * 8] = dcval_clamped;237pDst_ptr[5 * 8] = dcval_clamped;238pDst_ptr[6 * 8] = dcval_clamped;239pDst_ptr[7 * 8] = dcval_clamped;240}241};242243static const uint8 s_idct_row_table[] =244{2451,0,0,0,0,0,0,0, 2,0,0,0,0,0,0,0, 2,1,0,0,0,0,0,0, 2,1,1,0,0,0,0,0, 2,2,1,0,0,0,0,0, 3,2,1,0,0,0,0,0, 4,2,1,0,0,0,0,0, 4,3,1,0,0,0,0,0,2464,3,2,0,0,0,0,0, 4,3,2,1,0,0,0,0, 4,3,2,1,1,0,0,0, 4,3,2,2,1,0,0,0, 4,3,3,2,1,0,0,0, 4,4,3,2,1,0,0,0, 5,4,3,2,1,0,0,0, 6,4,3,2,1,0,0,0,2476,5,3,2,1,0,0,0, 6,5,4,2,1,0,0,0, 6,5,4,3,1,0,0,0, 6,5,4,3,2,0,0,0, 6,5,4,3,2,1,0,0, 6,5,4,3,2,1,1,0, 6,5,4,3,2,2,1,0, 6,5,4,3,3,2,1,0,2486,5,4,4,3,2,1,0, 6,5,5,4,3,2,1,0, 6,6,5,4,3,2,1,0, 7,6,5,4,3,2,1,0, 8,6,5,4,3,2,1,0, 8,7,5,4,3,2,1,0, 8,7,6,4,3,2,1,0, 8,7,6,5,3,2,1,0,2498,7,6,5,4,2,1,0, 8,7,6,5,4,3,1,0, 8,7,6,5,4,3,2,0, 8,7,6,5,4,3,2,1, 8,7,6,5,4,3,2,2, 8,7,6,5,4,3,3,2, 8,7,6,5,4,4,3,2, 8,7,6,5,5,4,3,2,2508,7,6,6,5,4,3,2, 8,7,7,6,5,4,3,2, 8,8,7,6,5,4,3,2, 8,8,8,6,5,4,3,2, 8,8,8,7,5,4,3,2, 8,8,8,7,6,4,3,2, 8,8,8,7,6,5,3,2, 8,8,8,7,6,5,4,2,2518,8,8,7,6,5,4,3, 8,8,8,7,6,5,4,4, 8,8,8,7,6,5,5,4, 8,8,8,7,6,6,5,4, 8,8,8,7,7,6,5,4, 8,8,8,8,7,6,5,4, 8,8,8,8,8,6,5,4, 8,8,8,8,8,7,5,4,2528,8,8,8,8,7,6,4, 8,8,8,8,8,7,6,5, 8,8,8,8,8,7,6,6, 8,8,8,8,8,7,7,6, 8,8,8,8,8,8,7,6, 8,8,8,8,8,8,8,6, 8,8,8,8,8,8,8,7, 8,8,8,8,8,8,8,8,253};254255static const uint8 s_idct_col_table[] =256{2571, 1, 2, 3, 3, 3, 3, 3, 3, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,2587, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8259};260261// Scalar "fast pathing" IDCT.262static void idct(const jpgd_block_t* pSrc_ptr, uint8* pDst_ptr, int block_max_zag)263{264assert(block_max_zag >= 1);265assert(block_max_zag <= 64);266267if (block_max_zag <= 1)268{269int k = ((pSrc_ptr[0] + 4) >> 3) + 128;270k = CLAMP(k);271k = k | (k << 8);272k = k | (k << 16);273274for (int i = 8; i > 0; i--)275{276*(int*)&pDst_ptr[0] = k;277*(int*)&pDst_ptr[4] = k;278pDst_ptr += 8;279}280return;281}282283int temp[64];284285const jpgd_block_t* pSrc = pSrc_ptr;286int* pTemp = temp;287288const uint8* pRow_tab = &s_idct_row_table[(block_max_zag - 1) * 8];289int i;290for (i = 8; i > 0; i--, pRow_tab++)291{292switch (*pRow_tab)293{294case 0: Row<0>::idct(pTemp, pSrc); break;295case 1: Row<1>::idct(pTemp, pSrc); break;296case 2: Row<2>::idct(pTemp, pSrc); break;297case 3: Row<3>::idct(pTemp, pSrc); break;298case 4: Row<4>::idct(pTemp, pSrc); break;299case 5: Row<5>::idct(pTemp, pSrc); break;300case 6: Row<6>::idct(pTemp, pSrc); break;301case 7: Row<7>::idct(pTemp, pSrc); break;302case 8: Row<8>::idct(pTemp, pSrc); break;303}304305pSrc += 8;306pTemp += 8;307}308309pTemp = temp;310311const int nonzero_rows = s_idct_col_table[block_max_zag - 1];312for (i = 8; i > 0; i--)313{314switch (nonzero_rows)315{316case 1: Col<1>::idct(pDst_ptr, pTemp); break;317case 2: Col<2>::idct(pDst_ptr, pTemp); break;318case 3: Col<3>::idct(pDst_ptr, pTemp); break;319case 4: Col<4>::idct(pDst_ptr, pTemp); break;320case 5: Col<5>::idct(pDst_ptr, pTemp); break;321case 6: Col<6>::idct(pDst_ptr, pTemp); break;322case 7: Col<7>::idct(pDst_ptr, pTemp); break;323case 8: Col<8>::idct(pDst_ptr, pTemp); break;324}325326pTemp++;327pDst_ptr++;328}329}330331// Retrieve one character from the input stream.332inline uint jpeg_decoder::get_char()333{334// Any bytes remaining in buffer?335if (!m_in_buf_left)336{337// Try to get more bytes.338prep_in_buffer();339// Still nothing to get?340if (!m_in_buf_left)341{342// Pad the end of the stream with 0xFF 0xD9 (EOI marker)343int t = m_tem_flag;344m_tem_flag ^= 1;345if (t)346return 0xD9;347else348return 0xFF;349}350}351352uint c = *m_pIn_buf_ofs++;353m_in_buf_left--;354355return c;356}357358// Same as previous method, except can indicate if the character is a pad character or not.359inline uint jpeg_decoder::get_char(bool* pPadding_flag)360{361if (!m_in_buf_left)362{363prep_in_buffer();364if (!m_in_buf_left)365{366*pPadding_flag = true;367int t = m_tem_flag;368m_tem_flag ^= 1;369if (t)370return 0xD9;371else372return 0xFF;373}374}375376*pPadding_flag = false;377378uint c = *m_pIn_buf_ofs++;379m_in_buf_left--;380381return c;382}383384// Inserts a previously retrieved character back into the input buffer.385inline void jpeg_decoder::stuff_char(uint8 q)386{387// This could write before the input buffer, but we've placed another array there.388*(--m_pIn_buf_ofs) = q;389m_in_buf_left++;390}391392// Retrieves one character from the input stream, but does not read past markers. Will continue to return 0xFF when a marker is encountered.393inline uint8 jpeg_decoder::get_octet()394{395bool padding_flag;396int c = get_char(&padding_flag);397398if (c == 0xFF)399{400if (padding_flag)401return 0xFF;402403c = get_char(&padding_flag);404if (padding_flag)405{406stuff_char(0xFF);407return 0xFF;408}409410if (c == 0x00)411return 0xFF;412else413{414stuff_char(static_cast<uint8>(c));415stuff_char(0xFF);416return 0xFF;417}418}419420return static_cast<uint8>(c);421}422423// Retrieves a variable number of bits from the input stream. Does not recognize markers.424inline uint jpeg_decoder::get_bits(int num_bits)425{426if (!num_bits)427return 0;428429uint i = m_bit_buf >> (32 - num_bits);430431if ((m_bits_left -= num_bits) <= 0)432{433m_bit_buf <<= (num_bits += m_bits_left);434435uint c1 = get_char();436uint c2 = get_char();437m_bit_buf = (m_bit_buf & 0xFFFF0000) | (c1 << 8) | c2;438439m_bit_buf <<= -m_bits_left;440441m_bits_left += 16;442443assert(m_bits_left >= 0);444}445else446m_bit_buf <<= num_bits;447448return i;449}450451// Retrieves a variable number of bits from the input stream. Markers will not be read into the input bit buffer. Instead, an infinite number of all 1's will be returned when a marker is encountered.452inline uint jpeg_decoder::get_bits_no_markers(int num_bits)453{454if (!num_bits)455return 0;456457assert(num_bits <= 16);458459uint i = m_bit_buf >> (32 - num_bits);460461if ((m_bits_left -= num_bits) <= 0)462{463m_bit_buf <<= (num_bits += m_bits_left);464465if ((m_in_buf_left < 2) || (m_pIn_buf_ofs[0] == 0xFF) || (m_pIn_buf_ofs[1] == 0xFF))466{467uint c1 = get_octet();468uint c2 = get_octet();469m_bit_buf |= (c1 << 8) | c2;470}471else472{473m_bit_buf |= ((uint)m_pIn_buf_ofs[0] << 8) | m_pIn_buf_ofs[1];474m_in_buf_left -= 2;475m_pIn_buf_ofs += 2;476}477478m_bit_buf <<= -m_bits_left;479480m_bits_left += 16;481482assert(m_bits_left >= 0);483}484else485m_bit_buf <<= num_bits;486487return i;488}489490// Decodes a Huffman encoded symbol.491inline int jpeg_decoder::huff_decode(huff_tables* pH)492{493if (!pH)494stop_decoding(JPGD_DECODE_ERROR);495496int symbol;497// Check first 8-bits: do we have a complete symbol?498if ((symbol = pH->look_up[m_bit_buf >> 24]) < 0)499{500// Decode more bits, use a tree traversal to find symbol.501int ofs = 23;502do503{504unsigned int idx = -(int)(symbol + ((m_bit_buf >> ofs) & 1));505506// This should never happen, but to be safe I'm turning these asserts into a run-time check.507if ((idx >= JPGD_HUFF_TREE_MAX_LENGTH) || (ofs < 0))508stop_decoding(JPGD_DECODE_ERROR);509510symbol = pH->tree[idx];511ofs--;512} while (symbol < 0);513514get_bits_no_markers(8 + (23 - ofs));515}516else517{518assert(symbol < JPGD_HUFF_CODE_SIZE_MAX_LENGTH);519get_bits_no_markers(pH->code_size[symbol]);520}521522return symbol;523}524525// Decodes a Huffman encoded symbol.526inline int jpeg_decoder::huff_decode(huff_tables* pH, int& extra_bits)527{528int symbol;529530if (!pH)531stop_decoding(JPGD_DECODE_ERROR);532533// Check first 8-bits: do we have a complete symbol?534if ((symbol = pH->look_up2[m_bit_buf >> 24]) < 0)535{536// Use a tree traversal to find symbol.537int ofs = 23;538do539{540unsigned int idx = -(int)(symbol + ((m_bit_buf >> ofs) & 1));541542// This should never happen, but to be safe I'm turning these asserts into a run-time check.543if ((idx >= JPGD_HUFF_TREE_MAX_LENGTH) || (ofs < 0))544stop_decoding(JPGD_DECODE_ERROR);545546symbol = pH->tree[idx];547ofs--;548} while (symbol < 0);549550get_bits_no_markers(8 + (23 - ofs));551552extra_bits = get_bits_no_markers(symbol & 0xF);553}554else555{556if (symbol & 0x8000)557{558//get_bits_no_markers((symbol >> 8) & 31);559assert(((symbol >> 8) & 31) <= 15);560get_bits_no_markers((symbol >> 8) & 15);561extra_bits = symbol >> 16;562}563else564{565int code_size = (symbol >> 8) & 31;566int num_extra_bits = symbol & 0xF;567int bits = code_size + num_extra_bits;568569if (bits <= 16)570extra_bits = get_bits_no_markers(bits) & ((1 << num_extra_bits) - 1);571else572{573get_bits_no_markers(code_size);574extra_bits = get_bits_no_markers(num_extra_bits);575}576}577578symbol &= 0xFF;579}580581return symbol;582}583584// Tables and macro used to fully decode the DPCM differences.585static const int s_extend_test[16] = { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 };586static const int s_extend_offset[16] = { 0, -1, -3, -7, -15, -31, -63, -127, -255, -511, -1023, -2047, -4095, -8191, -16383, -32767 };587//static const int s_extend_mask[] = { 0, (1 << 0), (1 << 1), (1 << 2), (1 << 3), (1 << 4), (1 << 5), (1 << 6), (1 << 7), (1 << 8), (1 << 9), (1 << 10), (1 << 11), (1 << 12), (1 << 13), (1 << 14), (1 << 15), (1 << 16) };588589#define JPGD_HUFF_EXTEND(x, s) (((x) < s_extend_test[s & 15]) ? ((x) + s_extend_offset[s & 15]) : (x))590591// Unconditionally frees all allocated m_blocks.592void jpeg_decoder::free_all_blocks()593{594m_pStream = nullptr;595for (mem_block* b = m_pMem_blocks; b; )596{597mem_block* n = b->m_pNext;598jpgd_free(b);599b = n;600}601m_pMem_blocks = nullptr;602}603604// This method handles all errors. It will never return.605// It could easily be changed to use C++ exceptions.606JPGD_NORETURN void jpeg_decoder::stop_decoding(jpgd_status status)607{608m_error_code = status;609free_all_blocks();610longjmp(m_jmp_state, status);611}612613void* jpeg_decoder::alloc(size_t nSize, bool zero)614{615nSize = (JPGD_MAX(nSize, 1) + 3) & ~3;616char* rv = nullptr;617for (mem_block* b = m_pMem_blocks; b; b = b->m_pNext)618{619if ((b->m_used_count + nSize) <= b->m_size)620{621rv = b->m_data + b->m_used_count;622b->m_used_count += nSize;623break;624}625}626if (!rv)627{628int capacity = JPGD_MAX(32768 - 256, ((int)nSize + 2047) & ~2047);629mem_block* b = (mem_block*)jpgd_malloc(sizeof(mem_block) + capacity);630if (!b)631{632stop_decoding(JPGD_NOTENOUGHMEM);633}634635b->m_pNext = m_pMem_blocks;636m_pMem_blocks = b;637b->m_used_count = nSize;638b->m_size = capacity;639rv = b->m_data;640}641if (zero) memset(rv, 0, nSize);642return rv;643}644645void jpeg_decoder::word_clear(void* p, uint16 c, uint n)646{647uint8* pD = (uint8*)p;648const uint8 l = c & 0xFF, h = (c >> 8) & 0xFF;649while (n)650{651pD[0] = l;652pD[1] = h;653pD += 2;654n--;655}656}657658// Refill the input buffer.659// This method will sit in a loop until (A) the buffer is full or (B)660// the stream's read() method reports and end of file condition.661void jpeg_decoder::prep_in_buffer()662{663m_in_buf_left = 0;664m_pIn_buf_ofs = m_in_buf;665666if (m_eof_flag)667return;668669do670{671int bytes_read = m_pStream->read(m_in_buf + m_in_buf_left, JPGD_IN_BUF_SIZE - m_in_buf_left, &m_eof_flag);672if (bytes_read == -1)673stop_decoding(JPGD_STREAM_READ);674675m_in_buf_left += bytes_read;676} while ((m_in_buf_left < JPGD_IN_BUF_SIZE) && (!m_eof_flag));677678m_total_bytes_read += m_in_buf_left;679680// Pad the end of the block with M_EOI (prevents the decompressor from going off the rails if the stream is invalid).681// (This dates way back to when this decompressor was written in C/asm, and the all-asm Huffman decoder did some fancy things to increase perf.)682word_clear(m_pIn_buf_ofs + m_in_buf_left, 0xD9FF, 64);683}684685// Read a Huffman code table.686void jpeg_decoder::read_dht_marker()687{688int i, index, count;689uint8 huff_num[17];690uint8 huff_val[256];691692uint num_left = get_bits(16);693694if (num_left < 2)695stop_decoding(JPGD_BAD_DHT_MARKER);696697num_left -= 2;698699while (num_left)700{701index = get_bits(8);702703huff_num[0] = 0;704705count = 0;706707for (i = 1; i <= 16; i++)708{709huff_num[i] = static_cast<uint8>(get_bits(8));710count += huff_num[i];711}712713if (count > 255)714stop_decoding(JPGD_BAD_DHT_COUNTS);715716bool symbol_present[256];717memset(symbol_present, 0, sizeof(symbol_present));718719for (i = 0; i < count; i++)720{721const int s = get_bits(8);722723// Check for obviously bogus tables.724if (symbol_present[s])725stop_decoding(JPGD_BAD_DHT_COUNTS);726727huff_val[i] = static_cast<uint8_t>(s);728symbol_present[s] = true;729}730731i = 1 + 16 + count;732733if (num_left < (uint)i)734stop_decoding(JPGD_BAD_DHT_MARKER);735736num_left -= i;737738if ((index & 0x10) > 0x10)739stop_decoding(JPGD_BAD_DHT_INDEX);740741index = (index & 0x0F) + ((index & 0x10) >> 4) * (JPGD_MAX_HUFF_TABLES >> 1);742743if (index >= JPGD_MAX_HUFF_TABLES)744stop_decoding(JPGD_BAD_DHT_INDEX);745746if (!m_huff_num[index])747m_huff_num[index] = (uint8*)alloc(17);748749if (!m_huff_val[index])750m_huff_val[index] = (uint8*)alloc(256);751752m_huff_ac[index] = (index & 0x10) != 0;753memcpy(m_huff_num[index], huff_num, 17);754memcpy(m_huff_val[index], huff_val, 256);755}756}757758// Read a quantization table.759void jpeg_decoder::read_dqt_marker()760{761int n, i, prec;762uint num_left;763uint temp;764765num_left = get_bits(16);766767if (num_left < 2)768stop_decoding(JPGD_BAD_DQT_MARKER);769770num_left -= 2;771772while (num_left)773{774n = get_bits(8);775prec = n >> 4;776n &= 0x0F;777778if (n >= JPGD_MAX_QUANT_TABLES)779stop_decoding(JPGD_BAD_DQT_TABLE);780781if (!m_quant[n])782m_quant[n] = (jpgd_quant_t*)alloc(64 * sizeof(jpgd_quant_t));783784// read quantization entries, in zag order785for (i = 0; i < 64; i++)786{787temp = get_bits(8);788789if (prec)790temp = (temp << 8) + get_bits(8);791792m_quant[n][i] = static_cast<jpgd_quant_t>(temp);793}794795i = 64 + 1;796797if (prec)798i += 64;799800if (num_left < (uint)i)801stop_decoding(JPGD_BAD_DQT_LENGTH);802803num_left -= i;804}805}806807// Read the start of frame (SOF) marker.808void jpeg_decoder::read_sof_marker()809{810int i;811uint num_left;812813num_left = get_bits(16);814815/* precision: sorry, only 8-bit precision is supported */816if (get_bits(8) != 8)817stop_decoding(JPGD_BAD_PRECISION);818819m_image_y_size = get_bits(16);820821if ((m_image_y_size < 1) || (m_image_y_size > JPGD_MAX_HEIGHT))822stop_decoding(JPGD_BAD_HEIGHT);823824m_image_x_size = get_bits(16);825826if ((m_image_x_size < 1) || (m_image_x_size > JPGD_MAX_WIDTH))827stop_decoding(JPGD_BAD_WIDTH);828829m_comps_in_frame = get_bits(8);830831if (m_comps_in_frame > JPGD_MAX_COMPONENTS)832stop_decoding(JPGD_TOO_MANY_COMPONENTS);833834if (num_left != (uint)(m_comps_in_frame * 3 + 8))835stop_decoding(JPGD_BAD_SOF_LENGTH);836837for (i = 0; i < m_comps_in_frame; i++)838{839m_comp_ident[i] = get_bits(8);840m_comp_h_samp[i] = get_bits(4);841m_comp_v_samp[i] = get_bits(4);842843if (!m_comp_h_samp[i] || !m_comp_v_samp[i] || (m_comp_h_samp[i] > 2) || (m_comp_v_samp[i] > 2))844stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS);845846m_comp_quant[i] = get_bits(8);847if (m_comp_quant[i] >= JPGD_MAX_QUANT_TABLES)848stop_decoding(JPGD_DECODE_ERROR);849}850}851852// Used to skip unrecognized markers.853void jpeg_decoder::skip_variable_marker()854{855uint num_left;856857num_left = get_bits(16);858859if (num_left < 2)860stop_decoding(JPGD_BAD_VARIABLE_MARKER);861862num_left -= 2;863864while (num_left)865{866get_bits(8);867num_left--;868}869}870871// Read a define restart interval (DRI) marker.872void jpeg_decoder::read_dri_marker()873{874if (get_bits(16) != 4)875stop_decoding(JPGD_BAD_DRI_LENGTH);876877m_restart_interval = get_bits(16);878}879880// Read a start of scan (SOS) marker.881void jpeg_decoder::read_sos_marker()882{883uint num_left;884int i, ci, n, c, cc;885886num_left = get_bits(16);887888n = get_bits(8);889890m_comps_in_scan = n;891892num_left -= 3;893894if ((num_left != (uint)(n * 2 + 3)) || (n < 1) || (n > JPGD_MAX_COMPS_IN_SCAN))895stop_decoding(JPGD_BAD_SOS_LENGTH);896897for (i = 0; i < n; i++)898{899cc = get_bits(8);900c = get_bits(8);901num_left -= 2;902903for (ci = 0; ci < m_comps_in_frame; ci++)904if (cc == m_comp_ident[ci])905break;906907if (ci >= m_comps_in_frame)908stop_decoding(JPGD_BAD_SOS_COMP_ID);909910if (ci >= JPGD_MAX_COMPONENTS)911stop_decoding(JPGD_DECODE_ERROR);912913m_comp_list[i] = ci;914915m_comp_dc_tab[ci] = (c >> 4) & 15;916m_comp_ac_tab[ci] = (c & 15) + (JPGD_MAX_HUFF_TABLES >> 1);917918if (m_comp_dc_tab[ci] >= JPGD_MAX_HUFF_TABLES)919stop_decoding(JPGD_DECODE_ERROR);920921if (m_comp_ac_tab[ci] >= JPGD_MAX_HUFF_TABLES)922stop_decoding(JPGD_DECODE_ERROR);923}924925m_spectral_start = get_bits(8);926m_spectral_end = get_bits(8);927m_successive_high = get_bits(4);928m_successive_low = get_bits(4);929930if (!m_progressive_flag)931{932m_spectral_start = 0;933m_spectral_end = 63;934}935936num_left -= 3;937938/* read past whatever is num_left */939while (num_left)940{941get_bits(8);942num_left--;943}944}945946// Finds the next marker.947int jpeg_decoder::next_marker()948{949uint c;// , bytes;950951//bytes = 0;952953do954{955do956{957//bytes++;958c = get_bits(8);959} while (c != 0xFF);960961do962{963c = get_bits(8);964} while (c == 0xFF);965966} while (c == 0);967968// If bytes > 0 here, there where extra bytes before the marker (not good).969970return c;971}972973// Process markers. Returns when an SOFx, SOI, EOI, or SOS marker is974// encountered.975int jpeg_decoder::process_markers()976{977int c;978979for (; ; )980{981c = next_marker();982983switch (c)984{985case M_SOF0:986case M_SOF1:987case M_SOF2:988case M_SOF3:989case M_SOF5:990case M_SOF6:991case M_SOF7:992// case M_JPG:993case M_SOF9:994case M_SOF10:995case M_SOF11:996case M_SOF13:997case M_SOF14:998case M_SOF15:999case M_SOI:1000case M_EOI:1001case M_SOS:1002{1003return c;1004}1005case M_DHT:1006{1007read_dht_marker();1008break;1009}1010// No arithmitic support - dumb patents!1011case M_DAC:1012{1013stop_decoding(JPGD_NO_ARITHMITIC_SUPPORT);1014break;1015}1016case M_DQT:1017{1018read_dqt_marker();1019break;1020}1021case M_DRI:1022{1023read_dri_marker();1024break;1025}1026//case M_APP0: /* no need to read the JFIF marker */1027case M_JPG:1028case M_RST0: /* no parameters */1029case M_RST1:1030case M_RST2:1031case M_RST3:1032case M_RST4:1033case M_RST5:1034case M_RST6:1035case M_RST7:1036case M_TEM:1037{1038stop_decoding(JPGD_UNEXPECTED_MARKER);1039break;1040}1041default: /* must be DNL, DHP, EXP, APPn, JPGn, COM, or RESn or APP0 */1042{1043skip_variable_marker();1044break;1045}1046}1047}1048}10491050// Finds the start of image (SOI) marker.1051void jpeg_decoder::locate_soi_marker()1052{1053uint lastchar, thischar;1054uint bytesleft;10551056lastchar = get_bits(8);10571058thischar = get_bits(8);10591060/* ok if it's a normal JPEG file without a special header */10611062if ((lastchar == 0xFF) && (thischar == M_SOI))1063return;10641065bytesleft = 4096;10661067for (; ; )1068{1069if (--bytesleft == 0)1070stop_decoding(JPGD_NOT_JPEG);10711072lastchar = thischar;10731074thischar = get_bits(8);10751076if (lastchar == 0xFF)1077{1078if (thischar == M_SOI)1079break;1080else if (thischar == M_EOI) // get_bits will keep returning M_EOI if we read past the end1081stop_decoding(JPGD_NOT_JPEG);1082}1083}10841085// Check the next character after marker: if it's not 0xFF, it can't be the start of the next marker, so the file is bad.1086thischar = (m_bit_buf >> 24) & 0xFF;10871088if (thischar != 0xFF)1089stop_decoding(JPGD_NOT_JPEG);1090}10911092// Find a start of frame (SOF) marker.1093void jpeg_decoder::locate_sof_marker()1094{1095locate_soi_marker();10961097int c = process_markers();10981099switch (c)1100{1101case M_SOF2:1102{1103m_progressive_flag = JPGD_TRUE;1104read_sof_marker();1105break;1106}1107case M_SOF0: /* baseline DCT */1108case M_SOF1: /* extended sequential DCT */1109{1110read_sof_marker();1111break;1112}1113case M_SOF9: /* Arithmitic coding */1114{1115stop_decoding(JPGD_NO_ARITHMITIC_SUPPORT);1116break;1117}1118default:1119{1120stop_decoding(JPGD_UNSUPPORTED_MARKER);1121break;1122}1123}1124}11251126// Find a start of scan (SOS) marker.1127int jpeg_decoder::locate_sos_marker()1128{1129int c;11301131c = process_markers();11321133if (c == M_EOI)1134return JPGD_FALSE;1135else if (c != M_SOS)1136stop_decoding(JPGD_UNEXPECTED_MARKER);11371138read_sos_marker();11391140return JPGD_TRUE;1141}11421143// Reset everything to default/uninitialized state.1144void jpeg_decoder::init(jpeg_decoder_stream* pStream, uint32_t flags)1145{1146m_flags = flags;1147m_pMem_blocks = nullptr;1148m_error_code = JPGD_SUCCESS;1149m_ready_flag = false;1150m_image_x_size = m_image_y_size = 0;1151m_pStream = pStream;1152m_progressive_flag = JPGD_FALSE;11531154memset(m_huff_ac, 0, sizeof(m_huff_ac));1155memset(m_huff_num, 0, sizeof(m_huff_num));1156memset(m_huff_val, 0, sizeof(m_huff_val));1157memset(m_quant, 0, sizeof(m_quant));11581159m_scan_type = 0;1160m_comps_in_frame = 0;11611162memset(m_comp_h_samp, 0, sizeof(m_comp_h_samp));1163memset(m_comp_v_samp, 0, sizeof(m_comp_v_samp));1164memset(m_comp_quant, 0, sizeof(m_comp_quant));1165memset(m_comp_ident, 0, sizeof(m_comp_ident));1166memset(m_comp_h_blocks, 0, sizeof(m_comp_h_blocks));1167memset(m_comp_v_blocks, 0, sizeof(m_comp_v_blocks));11681169m_comps_in_scan = 0;1170memset(m_comp_list, 0, sizeof(m_comp_list));1171memset(m_comp_dc_tab, 0, sizeof(m_comp_dc_tab));1172memset(m_comp_ac_tab, 0, sizeof(m_comp_ac_tab));11731174m_spectral_start = 0;1175m_spectral_end = 0;1176m_successive_low = 0;1177m_successive_high = 0;1178m_max_mcu_x_size = 0;1179m_max_mcu_y_size = 0;1180m_blocks_per_mcu = 0;1181m_max_blocks_per_row = 0;1182m_mcus_per_row = 0;1183m_mcus_per_col = 0;11841185memset(m_mcu_org, 0, sizeof(m_mcu_org));11861187m_total_lines_left = 0;1188m_mcu_lines_left = 0;1189m_num_buffered_scanlines = 0;1190m_real_dest_bytes_per_scan_line = 0;1191m_dest_bytes_per_scan_line = 0;1192m_dest_bytes_per_pixel = 0;11931194memset(m_pHuff_tabs, 0, sizeof(m_pHuff_tabs));11951196memset(m_dc_coeffs, 0, sizeof(m_dc_coeffs));1197memset(m_ac_coeffs, 0, sizeof(m_ac_coeffs));1198memset(m_block_y_mcu, 0, sizeof(m_block_y_mcu));11991200m_eob_run = 0;12011202m_pIn_buf_ofs = m_in_buf;1203m_in_buf_left = 0;1204m_eof_flag = false;1205m_tem_flag = 0;12061207memset(m_in_buf_pad_start, 0, sizeof(m_in_buf_pad_start));1208memset(m_in_buf, 0, sizeof(m_in_buf));1209memset(m_in_buf_pad_end, 0, sizeof(m_in_buf_pad_end));12101211m_restart_interval = 0;1212m_restarts_left = 0;1213m_next_restart_num = 0;12141215m_max_mcus_per_row = 0;1216m_max_blocks_per_mcu = 0;1217m_max_mcus_per_col = 0;12181219memset(m_last_dc_val, 0, sizeof(m_last_dc_val));1220m_pMCU_coefficients = nullptr;1221m_pSample_buf = nullptr;1222m_pSample_buf_prev = nullptr;1223m_sample_buf_prev_valid = false;12241225m_total_bytes_read = 0;12261227m_pScan_line_0 = nullptr;1228m_pScan_line_1 = nullptr;12291230// Ready the input buffer.1231prep_in_buffer();12321233// Prime the bit buffer.1234m_bits_left = 16;1235m_bit_buf = 0;12361237get_bits(16);1238get_bits(16);12391240for (int i = 0; i < JPGD_MAX_BLOCKS_PER_MCU; i++)1241m_mcu_block_max_zag[i] = 64;1242}12431244#define SCALEBITS 161245#define ONE_HALF ((int) 1 << (SCALEBITS-1))1246#define FIX(x) ((int) ((x) * (1L<<SCALEBITS) + 0.5f))12471248// Create a few tables that allow us to quickly convert YCbCr to RGB.1249void jpeg_decoder::create_look_ups()1250{1251for (int i = 0; i <= 255; i++)1252{1253int k = i - 128;1254m_crr[i] = (FIX(1.40200f) * k + ONE_HALF) >> SCALEBITS;1255m_cbb[i] = (FIX(1.77200f) * k + ONE_HALF) >> SCALEBITS;1256m_crg[i] = (-FIX(0.71414f)) * k;1257m_cbg[i] = (-FIX(0.34414f)) * k + ONE_HALF;1258}1259}12601261// This method throws back into the stream any bytes that where read1262// into the bit buffer during initial marker scanning.1263void jpeg_decoder::fix_in_buffer()1264{1265// In case any 0xFF's where pulled into the buffer during marker scanning.1266assert((m_bits_left & 7) == 0);12671268if (m_bits_left == 16)1269stuff_char((uint8)(m_bit_buf & 0xFF));12701271if (m_bits_left >= 8)1272stuff_char((uint8)((m_bit_buf >> 8) & 0xFF));12731274stuff_char((uint8)((m_bit_buf >> 16) & 0xFF));1275stuff_char((uint8)((m_bit_buf >> 24) & 0xFF));12761277m_bits_left = 16;1278get_bits_no_markers(16);1279get_bits_no_markers(16);1280}12811282void jpeg_decoder::transform_mcu(int mcu_row)1283{1284jpgd_block_t* pSrc_ptr = m_pMCU_coefficients;1285if (mcu_row * m_blocks_per_mcu >= m_max_blocks_per_row)1286stop_decoding(JPGD_DECODE_ERROR);12871288uint8* pDst_ptr = m_pSample_buf + mcu_row * m_blocks_per_mcu * 64;12891290for (int mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++)1291{1292idct(pSrc_ptr, pDst_ptr, m_mcu_block_max_zag[mcu_block]);1293pSrc_ptr += 64;1294pDst_ptr += 64;1295}1296}12971298// Loads and dequantizes the next row of (already decoded) coefficients.1299// Progressive images only.1300void jpeg_decoder::load_next_row()1301{1302int i;1303jpgd_block_t* p;1304jpgd_quant_t* q;1305int mcu_row, mcu_block;// , row_block = 0;1306int component_num, component_id;1307int block_x_mcu[JPGD_MAX_COMPONENTS];13081309memset(block_x_mcu, 0, JPGD_MAX_COMPONENTS * sizeof(int));13101311for (mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++)1312{1313int block_x_mcu_ofs = 0, block_y_mcu_ofs = 0;13141315for (mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++)1316{1317component_id = m_mcu_org[mcu_block];1318if (m_comp_quant[component_id] >= JPGD_MAX_QUANT_TABLES)1319stop_decoding(JPGD_DECODE_ERROR);13201321q = m_quant[m_comp_quant[component_id]];13221323p = m_pMCU_coefficients + 64 * mcu_block;13241325jpgd_block_t* pAC = coeff_buf_getp(m_ac_coeffs[component_id], block_x_mcu[component_id] + block_x_mcu_ofs, m_block_y_mcu[component_id] + block_y_mcu_ofs);1326jpgd_block_t* pDC = coeff_buf_getp(m_dc_coeffs[component_id], block_x_mcu[component_id] + block_x_mcu_ofs, m_block_y_mcu[component_id] + block_y_mcu_ofs);1327p[0] = pDC[0];1328memcpy(&p[1], &pAC[1], 63 * sizeof(jpgd_block_t));13291330for (i = 63; i > 0; i--)1331if (p[g_ZAG[i]])1332break;13331334m_mcu_block_max_zag[mcu_block] = i + 1;13351336for (; i >= 0; i--)1337if (p[g_ZAG[i]])1338p[g_ZAG[i]] = static_cast<jpgd_block_t>(p[g_ZAG[i]] * q[i]);13391340//row_block++;13411342if (m_comps_in_scan == 1)1343block_x_mcu[component_id]++;1344else1345{1346if (++block_x_mcu_ofs == m_comp_h_samp[component_id])1347{1348block_x_mcu_ofs = 0;13491350if (++block_y_mcu_ofs == m_comp_v_samp[component_id])1351{1352block_y_mcu_ofs = 0;13531354block_x_mcu[component_id] += m_comp_h_samp[component_id];1355}1356}1357}1358}13591360transform_mcu(mcu_row);1361}13621363if (m_comps_in_scan == 1)1364m_block_y_mcu[m_comp_list[0]]++;1365else1366{1367for (component_num = 0; component_num < m_comps_in_scan; component_num++)1368{1369component_id = m_comp_list[component_num];13701371m_block_y_mcu[component_id] += m_comp_v_samp[component_id];1372}1373}1374}13751376// Restart interval processing.1377void jpeg_decoder::process_restart()1378{1379int i;1380int c = 0;13811382// Align to a byte boundry1383// FIXME: Is this really necessary? get_bits_no_markers() never reads in markers!1384//get_bits_no_markers(m_bits_left & 7);13851386// Let's scan a little bit to find the marker, but not _too_ far.1387// 1536 is a "fudge factor" that determines how much to scan.1388for (i = 1536; i > 0; i--)1389if (get_char() == 0xFF)1390break;13911392if (i == 0)1393stop_decoding(JPGD_BAD_RESTART_MARKER);13941395for (; i > 0; i--)1396if ((c = get_char()) != 0xFF)1397break;13981399if (i == 0)1400stop_decoding(JPGD_BAD_RESTART_MARKER);14011402// Is it the expected marker? If not, something bad happened.1403if (c != (m_next_restart_num + M_RST0))1404stop_decoding(JPGD_BAD_RESTART_MARKER);14051406// Reset each component's DC prediction values.1407memset(&m_last_dc_val, 0, m_comps_in_frame * sizeof(uint));14081409m_eob_run = 0;14101411m_restarts_left = m_restart_interval;14121413m_next_restart_num = (m_next_restart_num + 1) & 7;14141415// Get the bit buffer going again...14161417m_bits_left = 16;1418get_bits_no_markers(16);1419get_bits_no_markers(16);1420}14211422static inline int dequantize_ac(int c, int q) { c *= q; return c; }14231424// Decodes and dequantizes the next row of coefficients.1425void jpeg_decoder::decode_next_row()1426{1427//int row_block = 0;14281429for (int mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++)1430{1431if ((m_restart_interval) && (m_restarts_left == 0))1432process_restart();14331434jpgd_block_t* p = m_pMCU_coefficients;1435for (int mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++, p += 64)1436{1437int component_id = m_mcu_org[mcu_block];1438if (m_comp_quant[component_id] >= JPGD_MAX_QUANT_TABLES)1439stop_decoding(JPGD_DECODE_ERROR);14401441jpgd_quant_t* q = m_quant[m_comp_quant[component_id]];14421443int r, s;1444s = huff_decode(m_pHuff_tabs[m_comp_dc_tab[component_id]], r);1445if (s >= 16)1446stop_decoding(JPGD_DECODE_ERROR);14471448s = JPGD_HUFF_EXTEND(r, s);14491450m_last_dc_val[component_id] = (s += m_last_dc_val[component_id]);14511452p[0] = static_cast<jpgd_block_t>(s * q[0]);14531454int prev_num_set = m_mcu_block_max_zag[mcu_block];14551456huff_tables* pH = m_pHuff_tabs[m_comp_ac_tab[component_id]];14571458int k;1459for (k = 1; k < 64; k++)1460{1461int extra_bits;1462s = huff_decode(pH, extra_bits);14631464r = s >> 4;1465s &= 15;14661467if (s)1468{1469if (r)1470{1471if ((k + r) > 63)1472stop_decoding(JPGD_DECODE_ERROR);14731474if (k < prev_num_set)1475{1476int n = JPGD_MIN(r, prev_num_set - k);1477int kt = k;1478while (n--)1479p[g_ZAG[kt++]] = 0;1480}14811482k += r;1483}14841485s = JPGD_HUFF_EXTEND(extra_bits, s);14861487if (k >= 64)1488stop_decoding(JPGD_DECODE_ERROR);14891490p[g_ZAG[k]] = static_cast<jpgd_block_t>(dequantize_ac(s, q[k])); //s * q[k];1491}1492else1493{1494if (r == 15)1495{1496if ((k + 16) > 64)1497stop_decoding(JPGD_DECODE_ERROR);14981499if (k < prev_num_set)1500{1501int n = JPGD_MIN(16, prev_num_set - k);1502int kt = k;1503while (n--)1504{1505if (kt > 63)1506stop_decoding(JPGD_DECODE_ERROR);1507p[g_ZAG[kt++]] = 0;1508}1509}15101511k += 16 - 1; // - 1 because the loop counter is k15121513if (p[g_ZAG[k & 63]] != 0)1514stop_decoding(JPGD_DECODE_ERROR);1515}1516else1517break;1518}1519}15201521if (k < prev_num_set)1522{1523int kt = k;1524while (kt < prev_num_set)1525p[g_ZAG[kt++]] = 0;1526}15271528m_mcu_block_max_zag[mcu_block] = k;15291530//row_block++;1531}15321533transform_mcu(mcu_row);15341535m_restarts_left--;1536}1537}15381539// YCbCr H1V1 (1x1:1:1, 3 m_blocks per MCU) to RGB1540void jpeg_decoder::H1V1Convert()1541{1542int row = m_max_mcu_y_size - m_mcu_lines_left;1543uint8* d = m_pScan_line_0;1544uint8* s = m_pSample_buf + row * 8;15451546for (int i = m_max_mcus_per_row; i > 0; i--)1547{1548for (int j = 0; j < 8; j++)1549{1550int y = s[j];1551int cb = s[64 + j];1552int cr = s[128 + j];15531554d[0] = clamp(y + m_crr[cr]);1555d[1] = clamp(y + ((m_crg[cr] + m_cbg[cb]) >> 16));1556d[2] = clamp(y + m_cbb[cb]);1557d[3] = 255;15581559d += 4;1560}15611562s += 64 * 3;1563}1564}15651566// YCbCr H2V1 (2x1:1:1, 4 m_blocks per MCU) to RGB1567void jpeg_decoder::H2V1Convert()1568{1569int row = m_max_mcu_y_size - m_mcu_lines_left;1570uint8* d0 = m_pScan_line_0;1571uint8* y = m_pSample_buf + row * 8;1572uint8* c = m_pSample_buf + 2 * 64 + row * 8;15731574for (int i = m_max_mcus_per_row; i > 0; i--)1575{1576for (int l = 0; l < 2; l++)1577{1578for (int j = 0; j < 4; j++)1579{1580int cb = c[0];1581int cr = c[64];15821583int rc = m_crr[cr];1584int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);1585int bc = m_cbb[cb];15861587int yy = y[j << 1];1588d0[0] = clamp(yy + rc);1589d0[1] = clamp(yy + gc);1590d0[2] = clamp(yy + bc);1591d0[3] = 255;15921593yy = y[(j << 1) + 1];1594d0[4] = clamp(yy + rc);1595d0[5] = clamp(yy + gc);1596d0[6] = clamp(yy + bc);1597d0[7] = 255;15981599d0 += 8;16001601c++;1602}1603y += 64;1604}16051606y += 64 * 4 - 64 * 2;1607c += 64 * 4 - 8;1608}1609}16101611// YCbCr H2V1 (2x1:1:1, 4 m_blocks per MCU) to RGB1612void jpeg_decoder::H2V1ConvertFiltered()1613{1614const uint BLOCKS_PER_MCU = 4;1615int row = m_max_mcu_y_size - m_mcu_lines_left;1616uint8* d0 = m_pScan_line_0;16171618const int half_image_x_size = (m_image_x_size >> 1) - 1;1619const int row_x8 = row * 8;16201621for (int x = 0; x < m_image_x_size; x++)1622{1623int y = m_pSample_buf[check_sample_buf_ofs((x >> 4) * BLOCKS_PER_MCU * 64 + ((x & 8) ? 64 : 0) + (x & 7) + row_x8)];16241625int c_x0 = (x - 1) >> 1;1626int c_x1 = JPGD_MIN(c_x0 + 1, half_image_x_size);1627c_x0 = JPGD_MAX(c_x0, 0);16281629int a = (c_x0 >> 3) * BLOCKS_PER_MCU * 64 + (c_x0 & 7) + row_x8 + 128;1630int cb0 = m_pSample_buf[check_sample_buf_ofs(a)];1631int cr0 = m_pSample_buf[check_sample_buf_ofs(a + 64)];16321633int b = (c_x1 >> 3) * BLOCKS_PER_MCU * 64 + (c_x1 & 7) + row_x8 + 128;1634int cb1 = m_pSample_buf[check_sample_buf_ofs(b)];1635int cr1 = m_pSample_buf[check_sample_buf_ofs(b + 64)];16361637int w0 = (x & 1) ? 3 : 1;1638int w1 = (x & 1) ? 1 : 3;16391640int cb = (cb0 * w0 + cb1 * w1 + 2) >> 2;1641int cr = (cr0 * w0 + cr1 * w1 + 2) >> 2;16421643int rc = m_crr[cr];1644int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);1645int bc = m_cbb[cb];16461647d0[0] = clamp(y + rc);1648d0[1] = clamp(y + gc);1649d0[2] = clamp(y + bc);1650d0[3] = 255;16511652d0 += 4;1653}1654}16551656// YCbCr H2V1 (1x2:1:1, 4 m_blocks per MCU) to RGB1657void jpeg_decoder::H1V2Convert()1658{1659int row = m_max_mcu_y_size - m_mcu_lines_left;1660uint8* d0 = m_pScan_line_0;1661uint8* d1 = m_pScan_line_1;1662uint8* y;1663uint8* c;16641665if (row < 8)1666y = m_pSample_buf + row * 8;1667else1668y = m_pSample_buf + 64 * 1 + (row & 7) * 8;16691670c = m_pSample_buf + 64 * 2 + (row >> 1) * 8;16711672for (int i = m_max_mcus_per_row; i > 0; i--)1673{1674for (int j = 0; j < 8; j++)1675{1676int cb = c[0 + j];1677int cr = c[64 + j];16781679int rc = m_crr[cr];1680int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);1681int bc = m_cbb[cb];16821683int yy = y[j];1684d0[0] = clamp(yy + rc);1685d0[1] = clamp(yy + gc);1686d0[2] = clamp(yy + bc);1687d0[3] = 255;16881689yy = y[8 + j];1690d1[0] = clamp(yy + rc);1691d1[1] = clamp(yy + gc);1692d1[2] = clamp(yy + bc);1693d1[3] = 255;16941695d0 += 4;1696d1 += 4;1697}16981699y += 64 * 4;1700c += 64 * 4;1701}1702}17031704// YCbCr H2V1 (1x2:1:1, 4 m_blocks per MCU) to RGB1705void jpeg_decoder::H1V2ConvertFiltered()1706{1707const uint BLOCKS_PER_MCU = 4;1708int y = m_image_y_size - m_total_lines_left;1709int row = y & 15;17101711const int half_image_y_size = (m_image_y_size >> 1) - 1;17121713uint8* d0 = m_pScan_line_0;17141715const int w0 = (row & 1) ? 3 : 1;1716const int w1 = (row & 1) ? 1 : 3;17171718int c_y0 = (y - 1) >> 1;1719int c_y1 = JPGD_MIN(c_y0 + 1, half_image_y_size);17201721const uint8_t* p_YSamples = m_pSample_buf;1722const uint8_t* p_C0Samples = m_pSample_buf;1723if ((c_y0 >= 0) && (((row & 15) == 0) || ((row & 15) == 15)) && (m_total_lines_left > 1))1724{1725assert(y > 0);1726assert(m_sample_buf_prev_valid);17271728if ((row & 15) == 15)1729p_YSamples = m_pSample_buf_prev;17301731p_C0Samples = m_pSample_buf_prev;1732}17331734const int y_sample_base_ofs = ((row & 8) ? 64 : 0) + (row & 7) * 8;1735const int y0_base = (c_y0 & 7) * 8 + 128;1736const int y1_base = (c_y1 & 7) * 8 + 128;17371738for (int x = 0; x < m_image_x_size; x++)1739{1740const int base_ofs = (x >> 3) * BLOCKS_PER_MCU * 64 + (x & 7);17411742int y_sample = p_YSamples[check_sample_buf_ofs(base_ofs + y_sample_base_ofs)];17431744int a = base_ofs + y0_base;1745int cb0_sample = p_C0Samples[check_sample_buf_ofs(a)];1746int cr0_sample = p_C0Samples[check_sample_buf_ofs(a + 64)];17471748int b = base_ofs + y1_base;1749int cb1_sample = m_pSample_buf[check_sample_buf_ofs(b)];1750int cr1_sample = m_pSample_buf[check_sample_buf_ofs(b + 64)];17511752int cb = (cb0_sample * w0 + cb1_sample * w1 + 2) >> 2;1753int cr = (cr0_sample * w0 + cr1_sample * w1 + 2) >> 2;17541755int rc = m_crr[cr];1756int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);1757int bc = m_cbb[cb];17581759d0[0] = clamp(y_sample + rc);1760d0[1] = clamp(y_sample + gc);1761d0[2] = clamp(y_sample + bc);1762d0[3] = 255;17631764d0 += 4;1765}1766}17671768// YCbCr H2V2 (2x2:1:1, 6 m_blocks per MCU) to RGB1769void jpeg_decoder::H2V2Convert()1770{1771int row = m_max_mcu_y_size - m_mcu_lines_left;1772uint8* d0 = m_pScan_line_0;1773uint8* d1 = m_pScan_line_1;1774uint8* y;1775uint8* c;17761777if (row < 8)1778y = m_pSample_buf + row * 8;1779else1780y = m_pSample_buf + 64 * 2 + (row & 7) * 8;17811782c = m_pSample_buf + 64 * 4 + (row >> 1) * 8;17831784for (int i = m_max_mcus_per_row; i > 0; i--)1785{1786for (int l = 0; l < 2; l++)1787{1788for (int j = 0; j < 8; j += 2)1789{1790int cb = c[0];1791int cr = c[64];17921793int rc = m_crr[cr];1794int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);1795int bc = m_cbb[cb];17961797int yy = y[j];1798d0[0] = clamp(yy + rc);1799d0[1] = clamp(yy + gc);1800d0[2] = clamp(yy + bc);1801d0[3] = 255;18021803yy = y[j + 1];1804d0[4] = clamp(yy + rc);1805d0[5] = clamp(yy + gc);1806d0[6] = clamp(yy + bc);1807d0[7] = 255;18081809yy = y[j + 8];1810d1[0] = clamp(yy + rc);1811d1[1] = clamp(yy + gc);1812d1[2] = clamp(yy + bc);1813d1[3] = 255;18141815yy = y[j + 8 + 1];1816d1[4] = clamp(yy + rc);1817d1[5] = clamp(yy + gc);1818d1[6] = clamp(yy + bc);1819d1[7] = 255;18201821d0 += 8;1822d1 += 8;18231824c++;1825}1826y += 64;1827}18281829y += 64 * 6 - 64 * 2;1830c += 64 * 6 - 8;1831}1832}18331834uint32_t jpeg_decoder::H2V2ConvertFiltered()1835{1836const uint BLOCKS_PER_MCU = 6;1837int y = m_image_y_size - m_total_lines_left;1838int row = y & 15;18391840const int half_image_y_size = (m_image_y_size >> 1) - 1;18411842uint8* d0 = m_pScan_line_0;18431844int c_y0 = (y - 1) >> 1;1845int c_y1 = JPGD_MIN(c_y0 + 1, half_image_y_size);18461847const uint8_t* p_YSamples = m_pSample_buf;1848const uint8_t* p_C0Samples = m_pSample_buf;1849if ((c_y0 >= 0) && (((row & 15) == 0) || ((row & 15) == 15)) && (m_total_lines_left > 1))1850{1851assert(y > 0);1852assert(m_sample_buf_prev_valid);18531854if ((row & 15) == 15)1855p_YSamples = m_pSample_buf_prev;18561857p_C0Samples = m_pSample_buf_prev;1858}18591860const int y_sample_base_ofs = ((row & 8) ? 128 : 0) + (row & 7) * 8;1861const int y0_base = (c_y0 & 7) * 8 + 256;1862const int y1_base = (c_y1 & 7) * 8 + 256;18631864const int half_image_x_size = (m_image_x_size >> 1) - 1;18651866static const uint8_t s_muls[2][2][4] =1867{1868{ { 1, 3, 3, 9 }, { 3, 9, 1, 3 }, },1869{ { 3, 1, 9, 3 }, { 9, 3, 3, 1 } }1870};18711872if (((row & 15) >= 1) && ((row & 15) <= 14))1873{1874assert((row & 1) == 1);1875assert(((y + 1 - 1) >> 1) == c_y0);18761877assert(p_YSamples == m_pSample_buf);1878assert(p_C0Samples == m_pSample_buf);18791880uint8* d1 = m_pScan_line_1;1881const int y_sample_base_ofs1 = (((row + 1) & 8) ? 128 : 0) + ((row + 1) & 7) * 8;18821883for (int x = 0; x < m_image_x_size; x++)1884{1885int k = (x >> 4) * BLOCKS_PER_MCU * 64 + ((x & 8) ? 64 : 0) + (x & 7);1886int y_sample0 = p_YSamples[check_sample_buf_ofs(k + y_sample_base_ofs)];1887int y_sample1 = p_YSamples[check_sample_buf_ofs(k + y_sample_base_ofs1)];18881889int c_x0 = (x - 1) >> 1;1890int c_x1 = JPGD_MIN(c_x0 + 1, half_image_x_size);1891c_x0 = JPGD_MAX(c_x0, 0);18921893int a = (c_x0 >> 3) * BLOCKS_PER_MCU * 64 + (c_x0 & 7);1894int cb00_sample = p_C0Samples[check_sample_buf_ofs(a + y0_base)];1895int cr00_sample = p_C0Samples[check_sample_buf_ofs(a + y0_base + 64)];18961897int cb01_sample = m_pSample_buf[check_sample_buf_ofs(a + y1_base)];1898int cr01_sample = m_pSample_buf[check_sample_buf_ofs(a + y1_base + 64)];18991900int b = (c_x1 >> 3) * BLOCKS_PER_MCU * 64 + (c_x1 & 7);1901int cb10_sample = p_C0Samples[check_sample_buf_ofs(b + y0_base)];1902int cr10_sample = p_C0Samples[check_sample_buf_ofs(b + y0_base + 64)];19031904int cb11_sample = m_pSample_buf[check_sample_buf_ofs(b + y1_base)];1905int cr11_sample = m_pSample_buf[check_sample_buf_ofs(b + y1_base + 64)];19061907{1908const uint8_t* pMuls = &s_muls[row & 1][x & 1][0];1909int cb = (cb00_sample * pMuls[0] + cb01_sample * pMuls[1] + cb10_sample * pMuls[2] + cb11_sample * pMuls[3] + 8) >> 4;1910int cr = (cr00_sample * pMuls[0] + cr01_sample * pMuls[1] + cr10_sample * pMuls[2] + cr11_sample * pMuls[3] + 8) >> 4;19111912int rc = m_crr[cr];1913int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);1914int bc = m_cbb[cb];19151916d0[0] = clamp(y_sample0 + rc);1917d0[1] = clamp(y_sample0 + gc);1918d0[2] = clamp(y_sample0 + bc);1919d0[3] = 255;19201921d0 += 4;1922}19231924{1925const uint8_t* pMuls = &s_muls[(row + 1) & 1][x & 1][0];1926int cb = (cb00_sample * pMuls[0] + cb01_sample * pMuls[1] + cb10_sample * pMuls[2] + cb11_sample * pMuls[3] + 8) >> 4;1927int cr = (cr00_sample * pMuls[0] + cr01_sample * pMuls[1] + cr10_sample * pMuls[2] + cr11_sample * pMuls[3] + 8) >> 4;19281929int rc = m_crr[cr];1930int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);1931int bc = m_cbb[cb];19321933d1[0] = clamp(y_sample1 + rc);1934d1[1] = clamp(y_sample1 + gc);1935d1[2] = clamp(y_sample1 + bc);1936d1[3] = 255;19371938d1 += 4;1939}19401941if (((x & 1) == 1) && (x < m_image_x_size - 1))1942{1943const int nx = x + 1;1944assert(c_x0 == (nx - 1) >> 1);19451946k = (nx >> 4) * BLOCKS_PER_MCU * 64 + ((nx & 8) ? 64 : 0) + (nx & 7);1947y_sample0 = p_YSamples[check_sample_buf_ofs(k + y_sample_base_ofs)];1948y_sample1 = p_YSamples[check_sample_buf_ofs(k + y_sample_base_ofs1)];19491950{1951const uint8_t* pMuls = &s_muls[row & 1][nx & 1][0];1952int cb = (cb00_sample * pMuls[0] + cb01_sample * pMuls[1] + cb10_sample * pMuls[2] + cb11_sample * pMuls[3] + 8) >> 4;1953int cr = (cr00_sample * pMuls[0] + cr01_sample * pMuls[1] + cr10_sample * pMuls[2] + cr11_sample * pMuls[3] + 8) >> 4;19541955int rc = m_crr[cr];1956int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);1957int bc = m_cbb[cb];19581959d0[0] = clamp(y_sample0 + rc);1960d0[1] = clamp(y_sample0 + gc);1961d0[2] = clamp(y_sample0 + bc);1962d0[3] = 255;19631964d0 += 4;1965}19661967{1968const uint8_t* pMuls = &s_muls[(row + 1) & 1][nx & 1][0];1969int cb = (cb00_sample * pMuls[0] + cb01_sample * pMuls[1] + cb10_sample * pMuls[2] + cb11_sample * pMuls[3] + 8) >> 4;1970int cr = (cr00_sample * pMuls[0] + cr01_sample * pMuls[1] + cr10_sample * pMuls[2] + cr11_sample * pMuls[3] + 8) >> 4;19711972int rc = m_crr[cr];1973int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);1974int bc = m_cbb[cb];19751976d1[0] = clamp(y_sample1 + rc);1977d1[1] = clamp(y_sample1 + gc);1978d1[2] = clamp(y_sample1 + bc);1979d1[3] = 255;19801981d1 += 4;1982}19831984++x;1985}1986}19871988return 2;1989}1990else1991{1992for (int x = 0; x < m_image_x_size; x++)1993{1994int y_sample = p_YSamples[check_sample_buf_ofs((x >> 4) * BLOCKS_PER_MCU * 64 + ((x & 8) ? 64 : 0) + (x & 7) + y_sample_base_ofs)];19951996int c_x0 = (x - 1) >> 1;1997int c_x1 = JPGD_MIN(c_x0 + 1, half_image_x_size);1998c_x0 = JPGD_MAX(c_x0, 0);19992000int a = (c_x0 >> 3) * BLOCKS_PER_MCU * 64 + (c_x0 & 7);2001int cb00_sample = p_C0Samples[check_sample_buf_ofs(a + y0_base)];2002int cr00_sample = p_C0Samples[check_sample_buf_ofs(a + y0_base + 64)];20032004int cb01_sample = m_pSample_buf[check_sample_buf_ofs(a + y1_base)];2005int cr01_sample = m_pSample_buf[check_sample_buf_ofs(a + y1_base + 64)];20062007int b = (c_x1 >> 3) * BLOCKS_PER_MCU * 64 + (c_x1 & 7);2008int cb10_sample = p_C0Samples[check_sample_buf_ofs(b + y0_base)];2009int cr10_sample = p_C0Samples[check_sample_buf_ofs(b + y0_base + 64)];20102011int cb11_sample = m_pSample_buf[check_sample_buf_ofs(b + y1_base)];2012int cr11_sample = m_pSample_buf[check_sample_buf_ofs(b + y1_base + 64)];20132014const uint8_t* pMuls = &s_muls[row & 1][x & 1][0];2015int cb = (cb00_sample * pMuls[0] + cb01_sample * pMuls[1] + cb10_sample * pMuls[2] + cb11_sample * pMuls[3] + 8) >> 4;2016int cr = (cr00_sample * pMuls[0] + cr01_sample * pMuls[1] + cr10_sample * pMuls[2] + cr11_sample * pMuls[3] + 8) >> 4;20172018int rc = m_crr[cr];2019int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);2020int bc = m_cbb[cb];20212022d0[0] = clamp(y_sample + rc);2023d0[1] = clamp(y_sample + gc);2024d0[2] = clamp(y_sample + bc);2025d0[3] = 255;20262027d0 += 4;2028}20292030return 1;2031}2032}20332034// Y (1 block per MCU) to 8-bit grayscale2035void jpeg_decoder::gray_convert()2036{2037int row = m_max_mcu_y_size - m_mcu_lines_left;2038uint8* d = m_pScan_line_0;2039uint8* s = m_pSample_buf + row * 8;20402041for (int i = m_max_mcus_per_row; i > 0; i--)2042{2043*(uint*)d = *(uint*)s;2044*(uint*)(&d[4]) = *(uint*)(&s[4]);20452046s += 64;2047d += 8;2048}2049}20502051// Find end of image (EOI) marker, so we can return to the user the exact size of the input stream.2052void jpeg_decoder::find_eoi()2053{2054if (!m_progressive_flag)2055{2056// Attempt to read the EOI marker.2057//get_bits_no_markers(m_bits_left & 7);20582059// Prime the bit buffer2060m_bits_left = 16;2061get_bits(16);2062get_bits(16);20632064// The next marker _should_ be EOI2065process_markers();2066}20672068m_total_bytes_read -= m_in_buf_left;2069}20702071int jpeg_decoder::decode_next_mcu_row()2072{2073if (setjmp(m_jmp_state))2074return JPGD_FAILED;20752076const bool chroma_y_filtering = (m_flags & cFlagLinearChromaFiltering) && ((m_scan_type == JPGD_YH2V2) || (m_scan_type == JPGD_YH1V2)) && (m_image_x_size >= 2) && (m_image_y_size >= 2);2077if (chroma_y_filtering)2078{2079std::swap(m_pSample_buf, m_pSample_buf_prev);20802081m_sample_buf_prev_valid = true;2082}20832084if (m_progressive_flag)2085load_next_row();2086else2087decode_next_row();20882089// Find the EOI marker if that was the last row.2090if (m_total_lines_left <= m_max_mcu_y_size)2091find_eoi();20922093m_mcu_lines_left = m_max_mcu_y_size;2094return 0;2095}20962097int jpeg_decoder::decode(const void** pScan_line, uint* pScan_line_len)2098{2099if ((m_error_code) || (!m_ready_flag))2100return JPGD_FAILED;21012102if (m_total_lines_left == 0)2103return JPGD_DONE;21042105const bool chroma_y_filtering = (m_flags & cFlagLinearChromaFiltering) && ((m_scan_type == JPGD_YH2V2) || (m_scan_type == JPGD_YH1V2)) && (m_image_x_size >= 2) && (m_image_y_size >= 2);21062107bool get_another_mcu_row = false;2108bool got_mcu_early = false;2109if (chroma_y_filtering)2110{2111if (m_total_lines_left == m_image_y_size)2112get_another_mcu_row = true;2113else if ((m_mcu_lines_left == 1) && (m_total_lines_left > 1))2114{2115get_another_mcu_row = true;2116got_mcu_early = true;2117}2118}2119else2120{2121get_another_mcu_row = (m_mcu_lines_left == 0);2122}21232124if (get_another_mcu_row)2125{2126int status = decode_next_mcu_row();2127if (status != 0)2128return status;2129}21302131switch (m_scan_type)2132{2133case JPGD_YH2V2:2134{2135if ((m_flags & cFlagLinearChromaFiltering) && (m_image_x_size >= 2) && (m_image_y_size >= 2))2136{2137if (m_num_buffered_scanlines == 1)2138{2139*pScan_line = m_pScan_line_1;2140}2141else if (m_num_buffered_scanlines == 0)2142{2143m_num_buffered_scanlines = H2V2ConvertFiltered();2144*pScan_line = m_pScan_line_0;2145}21462147m_num_buffered_scanlines--;2148}2149else2150{2151if ((m_mcu_lines_left & 1) == 0)2152{2153H2V2Convert();2154*pScan_line = m_pScan_line_0;2155}2156else2157*pScan_line = m_pScan_line_1;2158}21592160break;2161}2162case JPGD_YH2V1:2163{2164if ((m_flags & cFlagLinearChromaFiltering) && (m_image_x_size >= 2) && (m_image_y_size >= 2))2165H2V1ConvertFiltered();2166else2167H2V1Convert();2168*pScan_line = m_pScan_line_0;2169break;2170}2171case JPGD_YH1V2:2172{2173if (chroma_y_filtering)2174{2175H1V2ConvertFiltered();2176*pScan_line = m_pScan_line_0;2177}2178else2179{2180if ((m_mcu_lines_left & 1) == 0)2181{2182H1V2Convert();2183*pScan_line = m_pScan_line_0;2184}2185else2186*pScan_line = m_pScan_line_1;2187}21882189break;2190}2191case JPGD_YH1V1:2192{2193H1V1Convert();2194*pScan_line = m_pScan_line_0;2195break;2196}2197case JPGD_GRAYSCALE:2198{2199gray_convert();2200*pScan_line = m_pScan_line_0;22012202break;2203}2204}22052206*pScan_line_len = m_real_dest_bytes_per_scan_line;22072208if (!got_mcu_early)2209{2210m_mcu_lines_left--;2211}22122213m_total_lines_left--;22142215return JPGD_SUCCESS;2216}22172218// Creates the tables needed for efficient Huffman decoding.2219void jpeg_decoder::make_huff_table(int index, huff_tables* pH)2220{2221int p, i, l, si;2222uint8 huffsize[258];2223uint huffcode[258];2224uint code;2225uint subtree;2226int code_size;2227int lastp;2228int nextfreeentry;2229int currententry;22302231pH->ac_table = m_huff_ac[index] != 0;22322233p = 0;22342235for (l = 1; l <= 16; l++)2236{2237for (i = 1; i <= m_huff_num[index][l]; i++)2238{2239if (p >= 257)2240stop_decoding(JPGD_DECODE_ERROR);2241huffsize[p++] = static_cast<uint8>(l);2242}2243}22442245assert(p < 258);2246huffsize[p] = 0;22472248lastp = p;22492250code = 0;2251si = huffsize[0];2252p = 0;22532254while (huffsize[p])2255{2256while (huffsize[p] == si)2257{2258if (p >= 257)2259stop_decoding(JPGD_DECODE_ERROR);2260huffcode[p++] = code;2261code++;2262}22632264code <<= 1;2265si++;2266}22672268memset(pH->look_up, 0, sizeof(pH->look_up));2269memset(pH->look_up2, 0, sizeof(pH->look_up2));2270memset(pH->tree, 0, sizeof(pH->tree));2271memset(pH->code_size, 0, sizeof(pH->code_size));22722273nextfreeentry = -1;22742275p = 0;22762277while (p < lastp)2278{2279i = m_huff_val[index][p];22802281code = huffcode[p];2282code_size = huffsize[p];22832284assert(i < JPGD_HUFF_CODE_SIZE_MAX_LENGTH);2285pH->code_size[i] = static_cast<uint8>(code_size);22862287if (code_size <= 8)2288{2289code <<= (8 - code_size);22902291for (l = 1 << (8 - code_size); l > 0; l--)2292{2293if (code >= 256)2294stop_decoding(JPGD_DECODE_ERROR);22952296pH->look_up[code] = i;22972298bool has_extrabits = false;2299int extra_bits = 0;2300int num_extra_bits = i & 15;23012302int bits_to_fetch = code_size;2303if (num_extra_bits)2304{2305int total_codesize = code_size + num_extra_bits;2306if (total_codesize <= 8)2307{2308has_extrabits = true;2309extra_bits = ((1 << num_extra_bits) - 1) & (code >> (8 - total_codesize));23102311if (extra_bits > 0x7FFF)2312stop_decoding(JPGD_DECODE_ERROR);23132314bits_to_fetch += num_extra_bits;2315}2316}23172318if (!has_extrabits)2319pH->look_up2[code] = i | (bits_to_fetch << 8);2320else2321pH->look_up2[code] = i | 0x8000 | (extra_bits << 16) | (bits_to_fetch << 8);23222323code++;2324}2325}2326else2327{2328subtree = (code >> (code_size - 8)) & 0xFF;23292330currententry = pH->look_up[subtree];23312332if (currententry == 0)2333{2334pH->look_up[subtree] = currententry = nextfreeentry;2335pH->look_up2[subtree] = currententry = nextfreeentry;23362337nextfreeentry -= 2;2338}23392340code <<= (16 - (code_size - 8));23412342for (l = code_size; l > 9; l--)2343{2344if ((code & 0x8000) == 0)2345currententry--;23462347unsigned int idx = -currententry - 1;23482349if (idx >= JPGD_HUFF_TREE_MAX_LENGTH)2350stop_decoding(JPGD_DECODE_ERROR);23512352if (pH->tree[idx] == 0)2353{2354pH->tree[idx] = nextfreeentry;23552356currententry = nextfreeentry;23572358nextfreeentry -= 2;2359}2360else2361{2362currententry = pH->tree[idx];2363}23642365code <<= 1;2366}23672368if ((code & 0x8000) == 0)2369currententry--;23702371if ((-currententry - 1) >= JPGD_HUFF_TREE_MAX_LENGTH)2372stop_decoding(JPGD_DECODE_ERROR);23732374pH->tree[-currententry - 1] = i;2375}23762377p++;2378}2379}23802381// Verifies the quantization tables needed for this scan are available.2382void jpeg_decoder::check_quant_tables()2383{2384for (int i = 0; i < m_comps_in_scan; i++)2385if (m_quant[m_comp_quant[m_comp_list[i]]] == nullptr)2386stop_decoding(JPGD_UNDEFINED_QUANT_TABLE);2387}23882389// Verifies that all the Huffman tables needed for this scan are available.2390void jpeg_decoder::check_huff_tables()2391{2392for (int i = 0; i < m_comps_in_scan; i++)2393{2394if ((m_spectral_start == 0) && (m_huff_num[m_comp_dc_tab[m_comp_list[i]]] == nullptr))2395stop_decoding(JPGD_UNDEFINED_HUFF_TABLE);23962397if ((m_spectral_end > 0) && (m_huff_num[m_comp_ac_tab[m_comp_list[i]]] == nullptr))2398stop_decoding(JPGD_UNDEFINED_HUFF_TABLE);2399}24002401for (int i = 0; i < JPGD_MAX_HUFF_TABLES; i++)2402if (m_huff_num[i])2403{2404if (!m_pHuff_tabs[i])2405m_pHuff_tabs[i] = (huff_tables*)alloc(sizeof(huff_tables));24062407make_huff_table(i, m_pHuff_tabs[i]);2408}2409}24102411// Determines the component order inside each MCU.2412// Also calcs how many MCU's are on each row, etc.2413bool jpeg_decoder::calc_mcu_block_order()2414{2415int component_num, component_id;2416int max_h_samp = 0, max_v_samp = 0;24172418for (component_id = 0; component_id < m_comps_in_frame; component_id++)2419{2420if (m_comp_h_samp[component_id] > max_h_samp)2421max_h_samp = m_comp_h_samp[component_id];24222423if (m_comp_v_samp[component_id] > max_v_samp)2424max_v_samp = m_comp_v_samp[component_id];2425}24262427for (component_id = 0; component_id < m_comps_in_frame; component_id++)2428{2429m_comp_h_blocks[component_id] = ((((m_image_x_size * m_comp_h_samp[component_id]) + (max_h_samp - 1)) / max_h_samp) + 7) / 8;2430m_comp_v_blocks[component_id] = ((((m_image_y_size * m_comp_v_samp[component_id]) + (max_v_samp - 1)) / max_v_samp) + 7) / 8;2431}24322433if (m_comps_in_scan == 1)2434{2435m_mcus_per_row = m_comp_h_blocks[m_comp_list[0]];2436m_mcus_per_col = m_comp_v_blocks[m_comp_list[0]];2437}2438else2439{2440m_mcus_per_row = (((m_image_x_size + 7) / 8) + (max_h_samp - 1)) / max_h_samp;2441m_mcus_per_col = (((m_image_y_size + 7) / 8) + (max_v_samp - 1)) / max_v_samp;2442}24432444if (m_comps_in_scan == 1)2445{2446m_mcu_org[0] = m_comp_list[0];24472448m_blocks_per_mcu = 1;2449}2450else2451{2452m_blocks_per_mcu = 0;24532454for (component_num = 0; component_num < m_comps_in_scan; component_num++)2455{2456int num_blocks;24572458component_id = m_comp_list[component_num];24592460num_blocks = m_comp_h_samp[component_id] * m_comp_v_samp[component_id];24612462while (num_blocks--)2463m_mcu_org[m_blocks_per_mcu++] = component_id;2464}2465}24662467if (m_blocks_per_mcu > m_max_blocks_per_mcu)2468return false;24692470for (int mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++)2471{2472int comp_id = m_mcu_org[mcu_block];2473if (comp_id >= JPGD_MAX_QUANT_TABLES)2474return false;2475}24762477return true;2478}24792480// Starts a new scan.2481int jpeg_decoder::init_scan()2482{2483if (!locate_sos_marker())2484return JPGD_FALSE;24852486if (!calc_mcu_block_order())2487return JPGD_FALSE;24882489check_huff_tables();24902491check_quant_tables();24922493memset(m_last_dc_val, 0, m_comps_in_frame * sizeof(uint));24942495m_eob_run = 0;24962497if (m_restart_interval)2498{2499m_restarts_left = m_restart_interval;2500m_next_restart_num = 0;2501}25022503fix_in_buffer();25042505return JPGD_TRUE;2506}25072508// Starts a frame. Determines if the number of components or sampling factors2509// are supported.2510void jpeg_decoder::init_frame()2511{2512int i;25132514if (m_comps_in_frame == 1)2515{2516if ((m_comp_h_samp[0] != 1) || (m_comp_v_samp[0] != 1))2517stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS);25182519m_scan_type = JPGD_GRAYSCALE;2520m_max_blocks_per_mcu = 1;2521m_max_mcu_x_size = 8;2522m_max_mcu_y_size = 8;2523}2524else if (m_comps_in_frame == 3)2525{2526if (((m_comp_h_samp[1] != 1) || (m_comp_v_samp[1] != 1)) ||2527((m_comp_h_samp[2] != 1) || (m_comp_v_samp[2] != 1)))2528stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS);25292530if ((m_comp_h_samp[0] == 1) && (m_comp_v_samp[0] == 1))2531{2532m_scan_type = JPGD_YH1V1;25332534m_max_blocks_per_mcu = 3;2535m_max_mcu_x_size = 8;2536m_max_mcu_y_size = 8;2537}2538else if ((m_comp_h_samp[0] == 2) && (m_comp_v_samp[0] == 1))2539{2540m_scan_type = JPGD_YH2V1;2541m_max_blocks_per_mcu = 4;2542m_max_mcu_x_size = 16;2543m_max_mcu_y_size = 8;2544}2545else if ((m_comp_h_samp[0] == 1) && (m_comp_v_samp[0] == 2))2546{2547m_scan_type = JPGD_YH1V2;2548m_max_blocks_per_mcu = 4;2549m_max_mcu_x_size = 8;2550m_max_mcu_y_size = 16;2551}2552else if ((m_comp_h_samp[0] == 2) && (m_comp_v_samp[0] == 2))2553{2554m_scan_type = JPGD_YH2V2;2555m_max_blocks_per_mcu = 6;2556m_max_mcu_x_size = 16;2557m_max_mcu_y_size = 16;2558}2559else2560stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS);2561}2562else2563stop_decoding(JPGD_UNSUPPORTED_COLORSPACE);25642565m_max_mcus_per_row = (m_image_x_size + (m_max_mcu_x_size - 1)) / m_max_mcu_x_size;2566m_max_mcus_per_col = (m_image_y_size + (m_max_mcu_y_size - 1)) / m_max_mcu_y_size;25672568// These values are for the *destination* pixels: after conversion.2569if (m_scan_type == JPGD_GRAYSCALE)2570m_dest_bytes_per_pixel = 1;2571else2572m_dest_bytes_per_pixel = 4;25732574m_dest_bytes_per_scan_line = ((m_image_x_size + 15) & 0xFFF0) * m_dest_bytes_per_pixel;25752576m_real_dest_bytes_per_scan_line = (m_image_x_size * m_dest_bytes_per_pixel);25772578// Initialize two scan line buffers.2579m_pScan_line_0 = (uint8*)alloc(m_dest_bytes_per_scan_line, true);2580if ((m_scan_type == JPGD_YH1V2) || (m_scan_type == JPGD_YH2V2))2581m_pScan_line_1 = (uint8*)alloc(m_dest_bytes_per_scan_line, true);25822583m_max_blocks_per_row = m_max_mcus_per_row * m_max_blocks_per_mcu;25842585// Should never happen2586if (m_max_blocks_per_row > JPGD_MAX_BLOCKS_PER_ROW)2587stop_decoding(JPGD_DECODE_ERROR);25882589// Allocate the coefficient buffer, enough for one MCU2590m_pMCU_coefficients = (jpgd_block_t*)alloc(m_max_blocks_per_mcu * 64 * sizeof(jpgd_block_t));25912592for (i = 0; i < m_max_blocks_per_mcu; i++)2593m_mcu_block_max_zag[i] = 64;25942595m_pSample_buf = (uint8*)alloc(m_max_blocks_per_row * 64);2596m_pSample_buf_prev = (uint8*)alloc(m_max_blocks_per_row * 64);25972598m_total_lines_left = m_image_y_size;25992600m_mcu_lines_left = 0;26012602create_look_ups();2603}26042605// The coeff_buf series of methods originally stored the coefficients2606// into a "virtual" file which was located in EMS, XMS, or a disk file. A cache2607// was used to make this process more efficient. Now, we can store the entire2608// thing in RAM.2609jpeg_decoder::coeff_buf* jpeg_decoder::coeff_buf_open(int block_num_x, int block_num_y, int block_len_x, int block_len_y)2610{2611coeff_buf* cb = (coeff_buf*)alloc(sizeof(coeff_buf));26122613cb->block_num_x = block_num_x;2614cb->block_num_y = block_num_y;2615cb->block_len_x = block_len_x;2616cb->block_len_y = block_len_y;2617cb->block_size = (block_len_x * block_len_y) * sizeof(jpgd_block_t);2618cb->pData = (uint8*)alloc(cb->block_size * block_num_x * block_num_y, true);2619return cb;2620}26212622inline jpgd_block_t* jpeg_decoder::coeff_buf_getp(coeff_buf* cb, int block_x, int block_y)2623{2624if ((block_x >= cb->block_num_x) || (block_y >= cb->block_num_y))2625stop_decoding(JPGD_DECODE_ERROR);26262627return (jpgd_block_t*)(cb->pData + block_x * cb->block_size + block_y * (cb->block_size * cb->block_num_x));2628}26292630// The following methods decode the various types of m_blocks encountered2631// in progressively encoded images.2632void jpeg_decoder::decode_block_dc_first(jpeg_decoder* pD, int component_id, int block_x, int block_y)2633{2634int s, r;2635jpgd_block_t* p = pD->coeff_buf_getp(pD->m_dc_coeffs[component_id], block_x, block_y);26362637if ((s = pD->huff_decode(pD->m_pHuff_tabs[pD->m_comp_dc_tab[component_id]])) != 0)2638{2639if (s >= 16)2640pD->stop_decoding(JPGD_DECODE_ERROR);26412642r = pD->get_bits_no_markers(s);2643s = JPGD_HUFF_EXTEND(r, s);2644}26452646pD->m_last_dc_val[component_id] = (s += pD->m_last_dc_val[component_id]);26472648p[0] = static_cast<jpgd_block_t>(s << pD->m_successive_low);2649}26502651void jpeg_decoder::decode_block_dc_refine(jpeg_decoder* pD, int component_id, int block_x, int block_y)2652{2653if (pD->get_bits_no_markers(1))2654{2655jpgd_block_t* p = pD->coeff_buf_getp(pD->m_dc_coeffs[component_id], block_x, block_y);26562657p[0] |= (1 << pD->m_successive_low);2658}2659}26602661void jpeg_decoder::decode_block_ac_first(jpeg_decoder* pD, int component_id, int block_x, int block_y)2662{2663int k, s, r;26642665if (pD->m_eob_run)2666{2667pD->m_eob_run--;2668return;2669}26702671jpgd_block_t* p = pD->coeff_buf_getp(pD->m_ac_coeffs[component_id], block_x, block_y);26722673for (k = pD->m_spectral_start; k <= pD->m_spectral_end; k++)2674{2675unsigned int idx = pD->m_comp_ac_tab[component_id];2676if (idx >= JPGD_MAX_HUFF_TABLES)2677pD->stop_decoding(JPGD_DECODE_ERROR);26782679s = pD->huff_decode(pD->m_pHuff_tabs[idx]);26802681r = s >> 4;2682s &= 15;26832684if (s)2685{2686if ((k += r) > 63)2687pD->stop_decoding(JPGD_DECODE_ERROR);26882689r = pD->get_bits_no_markers(s);2690s = JPGD_HUFF_EXTEND(r, s);26912692p[g_ZAG[k]] = static_cast<jpgd_block_t>(s << pD->m_successive_low);2693}2694else2695{2696if (r == 15)2697{2698if ((k += 15) > 63)2699pD->stop_decoding(JPGD_DECODE_ERROR);2700}2701else2702{2703pD->m_eob_run = 1 << r;27042705if (r)2706pD->m_eob_run += pD->get_bits_no_markers(r);27072708pD->m_eob_run--;27092710break;2711}2712}2713}2714}27152716void jpeg_decoder::decode_block_ac_refine(jpeg_decoder* pD, int component_id, int block_x, int block_y)2717{2718int s, k, r;27192720int p1 = 1 << pD->m_successive_low;27212722//int m1 = (-1) << pD->m_successive_low;2723int m1 = static_cast<int>((UINT32_MAX << pD->m_successive_low));27242725jpgd_block_t* p = pD->coeff_buf_getp(pD->m_ac_coeffs[component_id], block_x, block_y);2726if (pD->m_spectral_end > 63)2727pD->stop_decoding(JPGD_DECODE_ERROR);27282729k = pD->m_spectral_start;27302731if (pD->m_eob_run == 0)2732{2733for (; k <= pD->m_spectral_end; k++)2734{2735unsigned int idx = pD->m_comp_ac_tab[component_id];2736if (idx >= JPGD_MAX_HUFF_TABLES)2737pD->stop_decoding(JPGD_DECODE_ERROR);27382739s = pD->huff_decode(pD->m_pHuff_tabs[idx]);27402741r = s >> 4;2742s &= 15;27432744if (s)2745{2746if (s != 1)2747pD->stop_decoding(JPGD_DECODE_ERROR);27482749if (pD->get_bits_no_markers(1))2750s = p1;2751else2752s = m1;2753}2754else2755{2756if (r != 15)2757{2758pD->m_eob_run = 1 << r;27592760if (r)2761pD->m_eob_run += pD->get_bits_no_markers(r);27622763break;2764}2765}27662767do2768{2769jpgd_block_t* this_coef = p + g_ZAG[k & 63];27702771if (*this_coef != 0)2772{2773if (pD->get_bits_no_markers(1))2774{2775if ((*this_coef & p1) == 0)2776{2777if (*this_coef >= 0)2778*this_coef = static_cast<jpgd_block_t>(*this_coef + p1);2779else2780*this_coef = static_cast<jpgd_block_t>(*this_coef + m1);2781}2782}2783}2784else2785{2786if (--r < 0)2787break;2788}27892790k++;27912792} while (k <= pD->m_spectral_end);27932794if ((s) && (k < 64))2795{2796p[g_ZAG[k]] = static_cast<jpgd_block_t>(s);2797}2798}2799}28002801if (pD->m_eob_run > 0)2802{2803for (; k <= pD->m_spectral_end; k++)2804{2805jpgd_block_t* this_coef = p + g_ZAG[k & 63]; // logical AND to shut up static code analysis28062807if (*this_coef != 0)2808{2809if (pD->get_bits_no_markers(1))2810{2811if ((*this_coef & p1) == 0)2812{2813if (*this_coef >= 0)2814*this_coef = static_cast<jpgd_block_t>(*this_coef + p1);2815else2816*this_coef = static_cast<jpgd_block_t>(*this_coef + m1);2817}2818}2819}2820}28212822pD->m_eob_run--;2823}2824}28252826// Decode a scan in a progressively encoded image.2827void jpeg_decoder::decode_scan(pDecode_block_func decode_block_func)2828{2829int mcu_row, mcu_col, mcu_block;2830int block_x_mcu[JPGD_MAX_COMPONENTS], block_y_mcu[JPGD_MAX_COMPONENTS];28312832memset(block_y_mcu, 0, sizeof(block_y_mcu));28332834for (mcu_col = 0; mcu_col < m_mcus_per_col; mcu_col++)2835{2836int component_num, component_id;28372838memset(block_x_mcu, 0, sizeof(block_x_mcu));28392840for (mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++)2841{2842int block_x_mcu_ofs = 0, block_y_mcu_ofs = 0;28432844if ((m_restart_interval) && (m_restarts_left == 0))2845process_restart();28462847for (mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++)2848{2849component_id = m_mcu_org[mcu_block];28502851decode_block_func(this, component_id, block_x_mcu[component_id] + block_x_mcu_ofs, block_y_mcu[component_id] + block_y_mcu_ofs);28522853if (m_comps_in_scan == 1)2854block_x_mcu[component_id]++;2855else2856{2857if (++block_x_mcu_ofs == m_comp_h_samp[component_id])2858{2859block_x_mcu_ofs = 0;28602861if (++block_y_mcu_ofs == m_comp_v_samp[component_id])2862{2863block_y_mcu_ofs = 0;2864block_x_mcu[component_id] += m_comp_h_samp[component_id];2865}2866}2867}2868}28692870m_restarts_left--;2871}28722873if (m_comps_in_scan == 1)2874block_y_mcu[m_comp_list[0]]++;2875else2876{2877for (component_num = 0; component_num < m_comps_in_scan; component_num++)2878{2879component_id = m_comp_list[component_num];2880block_y_mcu[component_id] += m_comp_v_samp[component_id];2881}2882}2883}2884}28852886// Decode a progressively encoded image.2887void jpeg_decoder::init_progressive()2888{2889int i;28902891if (m_comps_in_frame == 4)2892stop_decoding(JPGD_UNSUPPORTED_COLORSPACE);28932894// Allocate the coefficient buffers.2895for (i = 0; i < m_comps_in_frame; i++)2896{2897m_dc_coeffs[i] = coeff_buf_open(m_max_mcus_per_row * m_comp_h_samp[i], m_max_mcus_per_col * m_comp_v_samp[i], 1, 1);2898m_ac_coeffs[i] = coeff_buf_open(m_max_mcus_per_row * m_comp_h_samp[i], m_max_mcus_per_col * m_comp_v_samp[i], 8, 8);2899}29002901// See https://libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf2902uint32_t total_scans = 0;2903const uint32_t MAX_SCANS_TO_PROCESS = 1000;29042905for (; ; )2906{2907int dc_only_scan, refinement_scan;2908pDecode_block_func decode_block_func;29092910if (!init_scan())2911break;29122913dc_only_scan = (m_spectral_start == 0);2914refinement_scan = (m_successive_high != 0);29152916if ((m_spectral_start > m_spectral_end) || (m_spectral_end > 63))2917stop_decoding(JPGD_BAD_SOS_SPECTRAL);29182919if (dc_only_scan)2920{2921if (m_spectral_end)2922stop_decoding(JPGD_BAD_SOS_SPECTRAL);2923}2924else if (m_comps_in_scan != 1) /* AC scans can only contain one component */2925stop_decoding(JPGD_BAD_SOS_SPECTRAL);29262927if ((refinement_scan) && (m_successive_low != m_successive_high - 1))2928stop_decoding(JPGD_BAD_SOS_SUCCESSIVE);29292930if (dc_only_scan)2931{2932if (refinement_scan)2933decode_block_func = decode_block_dc_refine;2934else2935decode_block_func = decode_block_dc_first;2936}2937else2938{2939if (refinement_scan)2940decode_block_func = decode_block_ac_refine;2941else2942decode_block_func = decode_block_ac_first;2943}29442945decode_scan(decode_block_func);29462947m_bits_left = 16;2948get_bits(16);2949get_bits(16);29502951total_scans++;2952if (total_scans > MAX_SCANS_TO_PROCESS)2953stop_decoding(JPGD_TOO_MANY_SCANS);2954}29552956m_comps_in_scan = m_comps_in_frame;29572958for (i = 0; i < m_comps_in_frame; i++)2959m_comp_list[i] = i;29602961if (!calc_mcu_block_order())2962stop_decoding(JPGD_DECODE_ERROR);2963}29642965void jpeg_decoder::init_sequential()2966{2967if (!init_scan())2968stop_decoding(JPGD_UNEXPECTED_MARKER);2969}29702971void jpeg_decoder::decode_start()2972{2973init_frame();29742975if (m_progressive_flag)2976init_progressive();2977else2978init_sequential();2979}29802981void jpeg_decoder::decode_init(jpeg_decoder_stream* pStream, uint32_t flags)2982{2983init(pStream, flags);2984locate_sof_marker();2985}29862987jpeg_decoder::jpeg_decoder(jpeg_decoder_stream* pStream, uint32_t flags)2988{2989if (setjmp(m_jmp_state))2990return;2991decode_init(pStream, flags);2992}29932994int jpeg_decoder::begin_decoding()2995{2996if (m_ready_flag)2997return JPGD_SUCCESS;29982999if (m_error_code)3000return JPGD_FAILED;30013002if (setjmp(m_jmp_state))3003return JPGD_FAILED;30043005decode_start();30063007m_ready_flag = true;30083009return JPGD_SUCCESS;3010}30113012jpeg_decoder::~jpeg_decoder()3013{3014free_all_blocks();3015}30163017jpeg_decoder_file_stream::jpeg_decoder_file_stream()3018{3019m_pFile = nullptr;3020m_eof_flag = false;3021m_error_flag = false;3022}30233024void jpeg_decoder_file_stream::close()3025{3026if (m_pFile)3027{3028fclose(m_pFile);3029m_pFile = nullptr;3030}30313032m_eof_flag = false;3033m_error_flag = false;3034}30353036jpeg_decoder_file_stream::~jpeg_decoder_file_stream()3037{3038close();3039}30403041bool jpeg_decoder_file_stream::open(const char* Pfilename)3042{3043close();30443045m_eof_flag = false;3046m_error_flag = false;30473048#if defined(_MSC_VER)3049m_pFile = nullptr;3050fopen_s(&m_pFile, Pfilename, "rb");3051#else3052m_pFile = fopen(Pfilename, "rb");3053#endif3054return m_pFile != nullptr;3055}30563057int jpeg_decoder_file_stream::read(uint8* pBuf, int max_bytes_to_read, bool* pEOF_flag)3058{3059if (!m_pFile)3060return -1;30613062if (m_eof_flag)3063{3064*pEOF_flag = true;3065return 0;3066}30673068if (m_error_flag)3069return -1;30703071int bytes_read = static_cast<int>(fread(pBuf, 1, max_bytes_to_read, m_pFile));3072if (bytes_read < max_bytes_to_read)3073{3074if (ferror(m_pFile))3075{3076m_error_flag = true;3077return -1;3078}30793080m_eof_flag = true;3081*pEOF_flag = true;3082}30833084return bytes_read;3085}30863087bool jpeg_decoder_mem_stream::open(const uint8* pSrc_data, uint size)3088{3089close();3090m_pSrc_data = pSrc_data;3091m_ofs = 0;3092m_size = size;3093return true;3094}30953096int jpeg_decoder_mem_stream::read(uint8* pBuf, int max_bytes_to_read, bool* pEOF_flag)3097{3098*pEOF_flag = false;30993100if (!m_pSrc_data)3101return -1;31023103uint bytes_remaining = m_size - m_ofs;3104if ((uint)max_bytes_to_read > bytes_remaining)3105{3106max_bytes_to_read = bytes_remaining;3107*pEOF_flag = true;3108}31093110memcpy(pBuf, m_pSrc_data + m_ofs, max_bytes_to_read);3111m_ofs += max_bytes_to_read;31123113return max_bytes_to_read;3114}31153116unsigned char* decompress_jpeg_image_from_stream(jpeg_decoder_stream* pStream, int* width, int* height, int* actual_comps, int req_comps, uint32_t flags)3117{3118if (!actual_comps)3119return nullptr;3120*actual_comps = 0;31213122if ((!pStream) || (!width) || (!height) || (!req_comps))3123return nullptr;31243125if ((req_comps != 1) && (req_comps != 3) && (req_comps != 4))3126return nullptr;31273128jpeg_decoder decoder(pStream, flags);3129if (decoder.get_error_code() != JPGD_SUCCESS)3130return nullptr;31313132const int image_width = decoder.get_width(), image_height = decoder.get_height();3133*width = image_width;3134*height = image_height;3135*actual_comps = decoder.get_num_components();31363137if (decoder.begin_decoding() != JPGD_SUCCESS)3138return nullptr;31393140const int dst_bpl = image_width * req_comps;31413142uint8* pImage_data = (uint8*)jpgd_malloc(dst_bpl * image_height);3143if (!pImage_data)3144return nullptr;31453146for (int y = 0; y < image_height; y++)3147{3148const uint8* pScan_line;3149uint scan_line_len;3150if (decoder.decode((const void**)&pScan_line, &scan_line_len) != JPGD_SUCCESS)3151{3152jpgd_free(pImage_data);3153return nullptr;3154}31553156uint8* pDst = pImage_data + y * dst_bpl;31573158if (((req_comps == 1) && (decoder.get_num_components() == 1)) || ((req_comps == 4) && (decoder.get_num_components() == 3)))3159memcpy(pDst, pScan_line, dst_bpl);3160else if (decoder.get_num_components() == 1)3161{3162if (req_comps == 3)3163{3164for (int x = 0; x < image_width; x++)3165{3166uint8 luma = pScan_line[x];3167pDst[0] = luma;3168pDst[1] = luma;3169pDst[2] = luma;3170pDst += 3;3171}3172}3173else3174{3175for (int x = 0; x < image_width; x++)3176{3177uint8 luma = pScan_line[x];3178pDst[0] = luma;3179pDst[1] = luma;3180pDst[2] = luma;3181pDst[3] = 255;3182pDst += 4;3183}3184}3185}3186else if (decoder.get_num_components() == 3)3187{3188if (req_comps == 1)3189{3190const int YR = 19595, YG = 38470, YB = 7471;3191for (int x = 0; x < image_width; x++)3192{3193int r = pScan_line[x * 4 + 0];3194int g = pScan_line[x * 4 + 1];3195int b = pScan_line[x * 4 + 2];3196*pDst++ = static_cast<uint8>((r * YR + g * YG + b * YB + 32768) >> 16);3197}3198}3199else3200{3201for (int x = 0; x < image_width; x++)3202{3203pDst[0] = pScan_line[x * 4 + 0];3204pDst[1] = pScan_line[x * 4 + 1];3205pDst[2] = pScan_line[x * 4 + 2];3206pDst += 3;3207}3208}3209}3210}32113212return pImage_data;3213}32143215unsigned char* decompress_jpeg_image_from_memory(const unsigned char* pSrc_data, int src_data_size, int* width, int* height, int* actual_comps, int req_comps, uint32_t flags)3216{3217jpgd::jpeg_decoder_mem_stream mem_stream(pSrc_data, src_data_size);3218return decompress_jpeg_image_from_stream(&mem_stream, width, height, actual_comps, req_comps, flags);3219}32203221unsigned char* decompress_jpeg_image_from_file(const char* pSrc_filename, int* width, int* height, int* actual_comps, int req_comps, uint32_t flags)3222{3223jpgd::jpeg_decoder_file_stream file_stream;3224if (!file_stream.open(pSrc_filename))3225return nullptr;3226return decompress_jpeg_image_from_stream(&file_stream, width, height, actual_comps, req_comps, flags);3227}32283229} // namespace jpgd323032313232