CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/ext/jpge/jpgd.cpp
Views: 1401
// 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//25// Important:26// #define JPGD_USE_SSE2 to 0 to completely disable SSE2 usage.27//28#include "jpgd.h"29#include <string.h>30#include <algorithm>31#include <assert.h>3233#ifdef _MSC_VER34#pragma warning (disable : 4611) // warning C4611: interaction between '_setjmp' and C++ object destruction is non-portable35#endif3637#ifndef JPGD_USE_SSE23839#if defined(__GNUC__)40#if defined(__SSE2__)41#define JPGD_USE_SSE2 (1)42#endif43#elif defined(_MSC_VER)44#if defined(_M_X64)45#define JPGD_USE_SSE2 (1)46#endif47#endif4849#endif5051#define JPGD_TRUE (1)52#define JPGD_FALSE (0)5354#define JPGD_MAX(a,b) (((a)>(b)) ? (a) : (b))55#define JPGD_MIN(a,b) (((a)<(b)) ? (a) : (b))5657namespace jpgd {5859static inline void* jpgd_malloc(size_t nSize) { return malloc(nSize); }60static inline void jpgd_free(void* p) { free(p); }6162// DCT coefficients are stored in this sequence.63static 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 };6465enum JPEG_MARKER66{67M_SOF0 = 0xC0, M_SOF1 = 0xC1, M_SOF2 = 0xC2, M_SOF3 = 0xC3, M_SOF5 = 0xC5, M_SOF6 = 0xC6, M_SOF7 = 0xC7, M_JPG = 0xC8,68M_SOF9 = 0xC9, M_SOF10 = 0xCA, M_SOF11 = 0xCB, M_SOF13 = 0xCD, M_SOF14 = 0xCE, M_SOF15 = 0xCF, M_DHT = 0xC4, M_DAC = 0xCC,69M_RST0 = 0xD0, M_RST1 = 0xD1, M_RST2 = 0xD2, M_RST3 = 0xD3, M_RST4 = 0xD4, M_RST5 = 0xD5, M_RST6 = 0xD6, M_RST7 = 0xD7,70M_SOI = 0xD8, M_EOI = 0xD9, M_SOS = 0xDA, M_DQT = 0xDB, M_DNL = 0xDC, M_DRI = 0xDD, M_DHP = 0xDE, M_EXP = 0xDF,71M_APP0 = 0xE0, M_APP15 = 0xEF, M_JPG0 = 0xF0, M_JPG13 = 0xFD, M_COM = 0xFE, M_TEM = 0x01, M_ERROR = 0x100, RST0 = 0xD072};7374enum JPEG_SUBSAMPLING { JPGD_GRAYSCALE = 0, JPGD_YH1V1, JPGD_YH2V1, JPGD_YH1V2, JPGD_YH2V2 };7576#if JPGD_USE_SSE277#include "jpgd_idct.h"78#endif7980#define CONST_BITS 1381#define PASS1_BITS 282#define SCALEDONE ((int32)1)8384#define FIX_0_298631336 ((int32)2446) /* FIX(0.298631336) */85#define FIX_0_390180644 ((int32)3196) /* FIX(0.390180644) */86#define FIX_0_541196100 ((int32)4433) /* FIX(0.541196100) */87#define FIX_0_765366865 ((int32)6270) /* FIX(0.765366865) */88#define FIX_0_899976223 ((int32)7373) /* FIX(0.899976223) */89#define FIX_1_175875602 ((int32)9633) /* FIX(1.175875602) */90#define FIX_1_501321110 ((int32)12299) /* FIX(1.501321110) */91#define FIX_1_847759065 ((int32)15137) /* FIX(1.847759065) */92#define FIX_1_961570560 ((int32)16069) /* FIX(1.961570560) */93#define FIX_2_053119869 ((int32)16819) /* FIX(2.053119869) */94#define FIX_2_562915447 ((int32)20995) /* FIX(2.562915447) */95#define FIX_3_072711026 ((int32)25172) /* FIX(3.072711026) */9697#define DESCALE(x,n) (((x) + (SCALEDONE << ((n)-1))) >> (n))98#define DESCALE_ZEROSHIFT(x,n) (((x) + (128 << (n)) + (SCALEDONE << ((n)-1))) >> (n))99100#define MULTIPLY(var, cnst) ((var) * (cnst))101102#define CLAMP(i) ((static_cast<uint>(i) > 255) ? (((~i) >> 31) & 0xFF) : (i))103104static inline int left_shifti(int val, uint32_t bits)105{106return static_cast<int>(static_cast<uint32_t>(val) << bits);107}108109// Compiler creates a fast path 1D IDCT for X non-zero columns110template <int NONZERO_COLS>111struct Row112{113static void idct(int* pTemp, const jpgd_block_coeff_t* pSrc)114{115// ACCESS_COL() will be optimized at compile time to either an array access, or 0. Good compilers will then optimize out muls against 0.116#define ACCESS_COL(x) (((x) < NONZERO_COLS) ? (int)pSrc[x] : 0)117118const int z2 = ACCESS_COL(2), z3 = ACCESS_COL(6);119120const int z1 = MULTIPLY(z2 + z3, FIX_0_541196100);121const int tmp2 = z1 + MULTIPLY(z3, -FIX_1_847759065);122const int tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865);123124const int tmp0 = left_shifti(ACCESS_COL(0) + ACCESS_COL(4), CONST_BITS);125const int tmp1 = left_shifti(ACCESS_COL(0) - ACCESS_COL(4), CONST_BITS);126127const int tmp10 = tmp0 + tmp3, tmp13 = tmp0 - tmp3, tmp11 = tmp1 + tmp2, tmp12 = tmp1 - tmp2;128129const int atmp0 = ACCESS_COL(7), atmp1 = ACCESS_COL(5), atmp2 = ACCESS_COL(3), atmp3 = ACCESS_COL(1);130131const int bz1 = atmp0 + atmp3, bz2 = atmp1 + atmp2, bz3 = atmp0 + atmp2, bz4 = atmp1 + atmp3;132const int bz5 = MULTIPLY(bz3 + bz4, FIX_1_175875602);133134const int az1 = MULTIPLY(bz1, -FIX_0_899976223);135const int az2 = MULTIPLY(bz2, -FIX_2_562915447);136const int az3 = MULTIPLY(bz3, -FIX_1_961570560) + bz5;137const int az4 = MULTIPLY(bz4, -FIX_0_390180644) + bz5;138139const int btmp0 = MULTIPLY(atmp0, FIX_0_298631336) + az1 + az3;140const int btmp1 = MULTIPLY(atmp1, FIX_2_053119869) + az2 + az4;141const int btmp2 = MULTIPLY(atmp2, FIX_3_072711026) + az2 + az3;142const int btmp3 = MULTIPLY(atmp3, FIX_1_501321110) + az1 + az4;143144pTemp[0] = DESCALE(tmp10 + btmp3, CONST_BITS - PASS1_BITS);145pTemp[7] = DESCALE(tmp10 - btmp3, CONST_BITS - PASS1_BITS);146pTemp[1] = DESCALE(tmp11 + btmp2, CONST_BITS - PASS1_BITS);147pTemp[6] = DESCALE(tmp11 - btmp2, CONST_BITS - PASS1_BITS);148pTemp[2] = DESCALE(tmp12 + btmp1, CONST_BITS - PASS1_BITS);149pTemp[5] = DESCALE(tmp12 - btmp1, CONST_BITS - PASS1_BITS);150pTemp[3] = DESCALE(tmp13 + btmp0, CONST_BITS - PASS1_BITS);151pTemp[4] = DESCALE(tmp13 - btmp0, CONST_BITS - PASS1_BITS);152}153};154155template <>156struct Row<0>157{158static void idct(int* pTemp, const jpgd_block_coeff_t* pSrc)159{160(void)pTemp;161(void)pSrc;162}163};164165template <>166struct Row<1>167{168static void idct(int* pTemp, const jpgd_block_coeff_t* pSrc)169{170const int dcval = left_shifti(pSrc[0], PASS1_BITS);171172pTemp[0] = dcval;173pTemp[1] = dcval;174pTemp[2] = dcval;175pTemp[3] = dcval;176pTemp[4] = dcval;177pTemp[5] = dcval;178pTemp[6] = dcval;179pTemp[7] = dcval;180}181};182183// Compiler creates a fast path 1D IDCT for X non-zero rows184template <int NONZERO_ROWS>185struct Col186{187static void idct(uint8* pDst_ptr, const int* pTemp)188{189// ACCESS_ROW() will be optimized at compile time to either an array access, or 0.190#define ACCESS_ROW(x) (((x) < NONZERO_ROWS) ? pTemp[x * 8] : 0)191192const int z2 = ACCESS_ROW(2);193const int z3 = ACCESS_ROW(6);194195const int z1 = MULTIPLY(z2 + z3, FIX_0_541196100);196const int tmp2 = z1 + MULTIPLY(z3, -FIX_1_847759065);197const int tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865);198199const int tmp0 = left_shifti(ACCESS_ROW(0) + ACCESS_ROW(4), CONST_BITS);200const int tmp1 = left_shifti(ACCESS_ROW(0) - ACCESS_ROW(4), CONST_BITS);201202const int tmp10 = tmp0 + tmp3, tmp13 = tmp0 - tmp3, tmp11 = tmp1 + tmp2, tmp12 = tmp1 - tmp2;203204const int atmp0 = ACCESS_ROW(7), atmp1 = ACCESS_ROW(5), atmp2 = ACCESS_ROW(3), atmp3 = ACCESS_ROW(1);205206const int bz1 = atmp0 + atmp3, bz2 = atmp1 + atmp2, bz3 = atmp0 + atmp2, bz4 = atmp1 + atmp3;207const int bz5 = MULTIPLY(bz3 + bz4, FIX_1_175875602);208209const int az1 = MULTIPLY(bz1, -FIX_0_899976223);210const int az2 = MULTIPLY(bz2, -FIX_2_562915447);211const int az3 = MULTIPLY(bz3, -FIX_1_961570560) + bz5;212const int az4 = MULTIPLY(bz4, -FIX_0_390180644) + bz5;213214const int btmp0 = MULTIPLY(atmp0, FIX_0_298631336) + az1 + az3;215const int btmp1 = MULTIPLY(atmp1, FIX_2_053119869) + az2 + az4;216const int btmp2 = MULTIPLY(atmp2, FIX_3_072711026) + az2 + az3;217const int btmp3 = MULTIPLY(atmp3, FIX_1_501321110) + az1 + az4;218219int i = DESCALE_ZEROSHIFT(tmp10 + btmp3, CONST_BITS + PASS1_BITS + 3);220pDst_ptr[8 * 0] = (uint8)CLAMP(i);221222i = DESCALE_ZEROSHIFT(tmp10 - btmp3, CONST_BITS + PASS1_BITS + 3);223pDst_ptr[8 * 7] = (uint8)CLAMP(i);224225i = DESCALE_ZEROSHIFT(tmp11 + btmp2, CONST_BITS + PASS1_BITS + 3);226pDst_ptr[8 * 1] = (uint8)CLAMP(i);227228i = DESCALE_ZEROSHIFT(tmp11 - btmp2, CONST_BITS + PASS1_BITS + 3);229pDst_ptr[8 * 6] = (uint8)CLAMP(i);230231i = DESCALE_ZEROSHIFT(tmp12 + btmp1, CONST_BITS + PASS1_BITS + 3);232pDst_ptr[8 * 2] = (uint8)CLAMP(i);233234i = DESCALE_ZEROSHIFT(tmp12 - btmp1, CONST_BITS + PASS1_BITS + 3);235pDst_ptr[8 * 5] = (uint8)CLAMP(i);236237i = DESCALE_ZEROSHIFT(tmp13 + btmp0, CONST_BITS + PASS1_BITS + 3);238pDst_ptr[8 * 3] = (uint8)CLAMP(i);239240i = DESCALE_ZEROSHIFT(tmp13 - btmp0, CONST_BITS + PASS1_BITS + 3);241pDst_ptr[8 * 4] = (uint8)CLAMP(i);242}243};244245template <>246struct Col<1>247{248static void idct(uint8* pDst_ptr, const int* pTemp)249{250int dcval = DESCALE_ZEROSHIFT(pTemp[0], PASS1_BITS + 3);251const uint8 dcval_clamped = (uint8)CLAMP(dcval);252pDst_ptr[0 * 8] = dcval_clamped;253pDst_ptr[1 * 8] = dcval_clamped;254pDst_ptr[2 * 8] = dcval_clamped;255pDst_ptr[3 * 8] = dcval_clamped;256pDst_ptr[4 * 8] = dcval_clamped;257pDst_ptr[5 * 8] = dcval_clamped;258pDst_ptr[6 * 8] = dcval_clamped;259pDst_ptr[7 * 8] = dcval_clamped;260}261};262263static const uint8 s_idct_row_table[] =264{2651,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,2664,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,2676,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,2686,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,2698,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,2708,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,2718,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,2728,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,273};274275static const uint8 s_idct_col_table[] =276{2771, 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,2787, 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, 8279};280281// Scalar "fast pathing" IDCT.282static void idct(const jpgd_block_coeff_t* pSrc_ptr, uint8* pDst_ptr, int block_max_zag, bool use_simd)283{284(void)use_simd;285286assert(block_max_zag >= 1);287assert(block_max_zag <= 64);288289if (block_max_zag <= 1)290{291int k = ((pSrc_ptr[0] + 4) >> 3) + 128;292k = CLAMP(k);293k = k | (k << 8);294k = k | (k << 16);295296for (int i = 8; i > 0; i--)297{298*(int*)&pDst_ptr[0] = k;299*(int*)&pDst_ptr[4] = k;300pDst_ptr += 8;301}302return;303}304305#if JPGD_USE_SSE2306if (use_simd)307{308assert((((uintptr_t)pSrc_ptr) & 15) == 0);309assert((((uintptr_t)pDst_ptr) & 15) == 0);310idctSSEShortU8(pSrc_ptr, pDst_ptr);311return;312}313#endif314315int temp[64];316317const jpgd_block_coeff_t* pSrc = pSrc_ptr;318int* pTemp = temp;319320const uint8* pRow_tab = &s_idct_row_table[(block_max_zag - 1) * 8];321int i;322for (i = 8; i > 0; i--, pRow_tab++)323{324switch (*pRow_tab)325{326case 0: Row<0>::idct(pTemp, pSrc); break;327case 1: Row<1>::idct(pTemp, pSrc); break;328case 2: Row<2>::idct(pTemp, pSrc); break;329case 3: Row<3>::idct(pTemp, pSrc); break;330case 4: Row<4>::idct(pTemp, pSrc); break;331case 5: Row<5>::idct(pTemp, pSrc); break;332case 6: Row<6>::idct(pTemp, pSrc); break;333case 7: Row<7>::idct(pTemp, pSrc); break;334case 8: Row<8>::idct(pTemp, pSrc); break;335}336337pSrc += 8;338pTemp += 8;339}340341pTemp = temp;342343const int nonzero_rows = s_idct_col_table[block_max_zag - 1];344for (i = 8; i > 0; i--)345{346switch (nonzero_rows)347{348case 1: Col<1>::idct(pDst_ptr, pTemp); break;349case 2: Col<2>::idct(pDst_ptr, pTemp); break;350case 3: Col<3>::idct(pDst_ptr, pTemp); break;351case 4: Col<4>::idct(pDst_ptr, pTemp); break;352case 5: Col<5>::idct(pDst_ptr, pTemp); break;353case 6: Col<6>::idct(pDst_ptr, pTemp); break;354case 7: Col<7>::idct(pDst_ptr, pTemp); break;355case 8: Col<8>::idct(pDst_ptr, pTemp); break;356}357358pTemp++;359pDst_ptr++;360}361}362363// Retrieve one character from the input stream.364inline uint jpeg_decoder::get_char()365{366// Any bytes remaining in buffer?367if (!m_in_buf_left)368{369// Try to get more bytes.370prep_in_buffer();371// Still nothing to get?372if (!m_in_buf_left)373{374// Pad the end of the stream with 0xFF 0xD9 (EOI marker)375int t = m_tem_flag;376m_tem_flag ^= 1;377if (t)378return 0xD9;379else380return 0xFF;381}382}383384uint c = *m_pIn_buf_ofs++;385m_in_buf_left--;386387return c;388}389390// Same as previous method, except can indicate if the character is a pad character or not.391inline uint jpeg_decoder::get_char(bool* pPadding_flag)392{393if (!m_in_buf_left)394{395prep_in_buffer();396if (!m_in_buf_left)397{398*pPadding_flag = true;399int t = m_tem_flag;400m_tem_flag ^= 1;401if (t)402return 0xD9;403else404return 0xFF;405}406}407408*pPadding_flag = false;409410uint c = *m_pIn_buf_ofs++;411m_in_buf_left--;412413return c;414}415416// Inserts a previously retrieved character back into the input buffer.417inline void jpeg_decoder::stuff_char(uint8 q)418{419// This could write before the input buffer, but we've placed another array there.420*(--m_pIn_buf_ofs) = q;421m_in_buf_left++;422}423424// Retrieves one character from the input stream, but does not read past markers. Will continue to return 0xFF when a marker is encountered.425inline uint8 jpeg_decoder::get_octet()426{427bool padding_flag;428int c = get_char(&padding_flag);429430if (c == 0xFF)431{432if (padding_flag)433return 0xFF;434435c = get_char(&padding_flag);436if (padding_flag)437{438stuff_char(0xFF);439return 0xFF;440}441442if (c == 0x00)443return 0xFF;444else445{446stuff_char(static_cast<uint8>(c));447stuff_char(0xFF);448return 0xFF;449}450}451452return static_cast<uint8>(c);453}454455// Retrieves a variable number of bits from the input stream. Does not recognize markers.456inline uint jpeg_decoder::get_bits(int num_bits)457{458if (!num_bits)459return 0;460461uint i = m_bit_buf >> (32 - num_bits);462463if ((m_bits_left -= num_bits) <= 0)464{465m_bit_buf <<= (num_bits += m_bits_left);466467uint c1 = get_char();468uint c2 = get_char();469m_bit_buf = (m_bit_buf & 0xFFFF0000) | (c1 << 8) | c2;470471m_bit_buf <<= -m_bits_left;472473m_bits_left += 16;474475assert(m_bits_left >= 0);476}477else478m_bit_buf <<= num_bits;479480return i;481}482483// 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.484inline uint jpeg_decoder::get_bits_no_markers(int num_bits)485{486if (!num_bits)487return 0;488489assert(num_bits <= 16);490491uint i = m_bit_buf >> (32 - num_bits);492493if ((m_bits_left -= num_bits) <= 0)494{495m_bit_buf <<= (num_bits += m_bits_left);496497if ((m_in_buf_left < 2) || (m_pIn_buf_ofs[0] == 0xFF) || (m_pIn_buf_ofs[1] == 0xFF))498{499uint c1 = get_octet();500uint c2 = get_octet();501m_bit_buf |= (c1 << 8) | c2;502}503else504{505m_bit_buf |= ((uint)m_pIn_buf_ofs[0] << 8) | m_pIn_buf_ofs[1];506m_in_buf_left -= 2;507m_pIn_buf_ofs += 2;508}509510m_bit_buf <<= -m_bits_left;511512m_bits_left += 16;513514assert(m_bits_left >= 0);515}516else517m_bit_buf <<= num_bits;518519return i;520}521522// Decodes a Huffman encoded symbol.523inline int jpeg_decoder::huff_decode(huff_tables* pH)524{525if (!pH)526stop_decoding(JPGD_DECODE_ERROR);527528int symbol;529// Check first 8-bits: do we have a complete symbol?530if ((symbol = pH->look_up[m_bit_buf >> 24]) < 0)531{532// Decode more bits, use a tree traversal to find symbol.533int ofs = 23;534do535{536unsigned int idx = -(int)(symbol + ((m_bit_buf >> ofs) & 1));537538// This should never happen, but to be safe I'm turning these asserts into a run-time check.539if ((idx >= JPGD_HUFF_TREE_MAX_LENGTH) || (ofs < 0))540stop_decoding(JPGD_DECODE_ERROR);541542symbol = pH->tree[idx];543ofs--;544} while (symbol < 0);545546get_bits_no_markers(8 + (23 - ofs));547}548else549{550assert(symbol < JPGD_HUFF_CODE_SIZE_MAX_LENGTH);551get_bits_no_markers(pH->code_size[symbol]);552}553554return symbol;555}556557// Decodes a Huffman encoded symbol.558inline int jpeg_decoder::huff_decode(huff_tables* pH, int& extra_bits)559{560int symbol;561562if (!pH)563stop_decoding(JPGD_DECODE_ERROR);564565// Check first 8-bits: do we have a complete symbol?566if ((symbol = pH->look_up2[m_bit_buf >> 24]) < 0)567{568// Use a tree traversal to find symbol.569int ofs = 23;570do571{572unsigned int idx = -(int)(symbol + ((m_bit_buf >> ofs) & 1));573574// This should never happen, but to be safe I'm turning these asserts into a run-time check.575if ((idx >= JPGD_HUFF_TREE_MAX_LENGTH) || (ofs < 0))576stop_decoding(JPGD_DECODE_ERROR);577578symbol = pH->tree[idx];579ofs--;580} while (symbol < 0);581582get_bits_no_markers(8 + (23 - ofs));583584extra_bits = get_bits_no_markers(symbol & 0xF);585}586else587{588if (symbol & 0x8000)589{590//get_bits_no_markers((symbol >> 8) & 31);591assert(((symbol >> 8) & 31) <= 15);592get_bits_no_markers((symbol >> 8) & 15);593extra_bits = symbol >> 16;594}595else596{597int code_size = (symbol >> 8) & 31;598int num_extra_bits = symbol & 0xF;599int bits = code_size + num_extra_bits;600601if (bits <= 16)602extra_bits = get_bits_no_markers(bits) & ((1 << num_extra_bits) - 1);603else604{605get_bits_no_markers(code_size);606extra_bits = get_bits_no_markers(num_extra_bits);607}608}609610symbol &= 0xFF;611}612613return symbol;614}615616// Tables and macro used to fully decode the DPCM differences.617static const int s_extend_test[16] = { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 };618static const int s_extend_offset[16] = { 0, -1, -3, -7, -15, -31, -63, -127, -255, -511, -1023, -2047, -4095, -8191, -16383, -32767 };619//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) };620621#define JPGD_HUFF_EXTEND(x, s) (((x) < s_extend_test[s & 15]) ? ((x) + s_extend_offset[s & 15]) : (x))622623// Unconditionally frees all allocated m_blocks.624void jpeg_decoder::free_all_blocks()625{626m_pStream = nullptr;627for (mem_block* b = m_pMem_blocks; b; )628{629mem_block* n = b->m_pNext;630jpgd_free(b);631b = n;632}633m_pMem_blocks = nullptr;634}635636// This method handles all errors. It will never return.637// It could easily be changed to use C++ exceptions.638JPGD_NORETURN void jpeg_decoder::stop_decoding(jpgd_status status)639{640m_error_code = status;641free_all_blocks();642longjmp(m_jmp_state, status);643}644645void* jpeg_decoder::alloc(size_t nSize, bool zero)646{647nSize = (JPGD_MAX(nSize, 1) + 3) & ~3;648char* rv = nullptr;649for (mem_block* b = m_pMem_blocks; b; b = b->m_pNext)650{651if ((b->m_used_count + nSize) <= b->m_size)652{653rv = b->m_data + b->m_used_count;654b->m_used_count += nSize;655break;656}657}658if (!rv)659{660int capacity = JPGD_MAX(32768 - 256, (nSize + 2047) & ~2047);661mem_block* b = (mem_block*)jpgd_malloc(sizeof(mem_block) + capacity);662if (!b)663{664stop_decoding(JPGD_NOTENOUGHMEM);665}666667b->m_pNext = m_pMem_blocks;668m_pMem_blocks = b;669b->m_used_count = nSize;670b->m_size = capacity;671rv = b->m_data;672}673if (zero) memset(rv, 0, nSize);674return rv;675}676677void* jpeg_decoder::alloc_aligned(size_t nSize, uint32_t align, bool zero)678{679assert((align >= 1U) && ((align & (align - 1U)) == 0U));680void *p = alloc(nSize + align - 1U, zero);681p = (void *)( ((uintptr_t)p + (align - 1U)) & ~((uintptr_t)(align - 1U)) );682return p;683}684685void jpeg_decoder::word_clear(void* p, uint16 c, uint n)686{687uint8* pD = (uint8*)p;688const uint8 l = c & 0xFF, h = (c >> 8) & 0xFF;689while (n)690{691pD[0] = l;692pD[1] = h;693pD += 2;694n--;695}696}697698// Refill the input buffer.699// This method will sit in a loop until (A) the buffer is full or (B)700// the stream's read() method reports and end of file condition.701void jpeg_decoder::prep_in_buffer()702{703m_in_buf_left = 0;704m_pIn_buf_ofs = m_in_buf;705706if (m_eof_flag)707return;708709do710{711int bytes_read = m_pStream->read(m_in_buf + m_in_buf_left, JPGD_IN_BUF_SIZE - m_in_buf_left, &m_eof_flag);712if (bytes_read == -1)713stop_decoding(JPGD_STREAM_READ);714715m_in_buf_left += bytes_read;716} while ((m_in_buf_left < JPGD_IN_BUF_SIZE) && (!m_eof_flag));717718m_total_bytes_read += m_in_buf_left;719720// Pad the end of the block with M_EOI (prevents the decompressor from going off the rails if the stream is invalid).721// (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.)722word_clear(m_pIn_buf_ofs + m_in_buf_left, 0xD9FF, 64);723}724725// Read a Huffman code table.726void jpeg_decoder::read_dht_marker()727{728int i, index, count;729uint8 huff_num[17];730uint8 huff_val[256];731732uint num_left = get_bits(16);733734if (num_left < 2)735stop_decoding(JPGD_BAD_DHT_MARKER);736737num_left -= 2;738739while (num_left)740{741index = get_bits(8);742743huff_num[0] = 0;744745count = 0;746747for (i = 1; i <= 16; i++)748{749huff_num[i] = static_cast<uint8>(get_bits(8));750count += huff_num[i];751}752753if (count > 255)754stop_decoding(JPGD_BAD_DHT_COUNTS);755756bool symbol_present[256];757memset(symbol_present, 0, sizeof(symbol_present));758759for (i = 0; i < count; i++)760{761const int s = get_bits(8);762763// Check for obviously bogus tables.764if (symbol_present[s])765stop_decoding(JPGD_BAD_DHT_COUNTS);766767huff_val[i] = static_cast<uint8_t>(s);768symbol_present[s] = true;769}770771i = 1 + 16 + count;772773if (num_left < (uint)i)774stop_decoding(JPGD_BAD_DHT_MARKER);775776num_left -= i;777778if ((index & 0x10) > 0x10)779stop_decoding(JPGD_BAD_DHT_INDEX);780781index = (index & 0x0F) + ((index & 0x10) >> 4) * (JPGD_MAX_HUFF_TABLES >> 1);782783if (index >= JPGD_MAX_HUFF_TABLES)784stop_decoding(JPGD_BAD_DHT_INDEX);785786if (!m_huff_num[index])787m_huff_num[index] = (uint8*)alloc(17);788789if (!m_huff_val[index])790m_huff_val[index] = (uint8*)alloc(256);791792m_huff_ac[index] = (index & 0x10) != 0;793memcpy(m_huff_num[index], huff_num, 17);794memcpy(m_huff_val[index], huff_val, 256);795}796}797798// Read a quantization table.799void jpeg_decoder::read_dqt_marker()800{801int n, i, prec;802uint num_left;803uint temp;804805num_left = get_bits(16);806807if (num_left < 2)808stop_decoding(JPGD_BAD_DQT_MARKER);809810num_left -= 2;811812while (num_left)813{814n = get_bits(8);815prec = n >> 4;816n &= 0x0F;817818if (n >= JPGD_MAX_QUANT_TABLES)819stop_decoding(JPGD_BAD_DQT_TABLE);820821if (!m_quant[n])822m_quant[n] = (jpgd_quant_t*)alloc(64 * sizeof(jpgd_quant_t));823824// read quantization entries, in zag order825for (i = 0; i < 64; i++)826{827temp = get_bits(8);828829if (prec)830temp = (temp << 8) + get_bits(8);831832m_quant[n][i] = static_cast<jpgd_quant_t>(temp);833}834835i = 64 + 1;836837if (prec)838i += 64;839840if (num_left < (uint)i)841stop_decoding(JPGD_BAD_DQT_LENGTH);842843num_left -= i;844}845}846847// Read the start of frame (SOF) marker.848void jpeg_decoder::read_sof_marker()849{850int i;851uint num_left;852853num_left = get_bits(16);854855/* precision: sorry, only 8-bit precision is supported */856if (get_bits(8) != 8)857stop_decoding(JPGD_BAD_PRECISION);858859m_image_y_size = get_bits(16);860861if ((m_image_y_size < 1) || (m_image_y_size > JPGD_MAX_HEIGHT))862stop_decoding(JPGD_BAD_HEIGHT);863864m_image_x_size = get_bits(16);865866if ((m_image_x_size < 1) || (m_image_x_size > JPGD_MAX_WIDTH))867stop_decoding(JPGD_BAD_WIDTH);868869m_comps_in_frame = get_bits(8);870871if (m_comps_in_frame > JPGD_MAX_COMPONENTS)872stop_decoding(JPGD_TOO_MANY_COMPONENTS);873874if (num_left != (uint)(m_comps_in_frame * 3 + 8))875stop_decoding(JPGD_BAD_SOF_LENGTH);876877for (i = 0; i < m_comps_in_frame; i++)878{879m_comp_ident[i] = get_bits(8);880m_comp_h_samp[i] = get_bits(4);881m_comp_v_samp[i] = get_bits(4);882883if (!m_comp_h_samp[i] || !m_comp_v_samp[i] || (m_comp_h_samp[i] > 2) || (m_comp_v_samp[i] > 2))884stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS);885886m_comp_quant[i] = get_bits(8);887if (m_comp_quant[i] >= JPGD_MAX_QUANT_TABLES)888stop_decoding(JPGD_DECODE_ERROR);889}890}891892// Used to skip unrecognized markers.893void jpeg_decoder::skip_variable_marker()894{895uint num_left;896897num_left = get_bits(16);898899if (num_left < 2)900stop_decoding(JPGD_BAD_VARIABLE_MARKER);901902num_left -= 2;903904while (num_left)905{906get_bits(8);907num_left--;908}909}910911// Read a define restart interval (DRI) marker.912void jpeg_decoder::read_dri_marker()913{914if (get_bits(16) != 4)915stop_decoding(JPGD_BAD_DRI_LENGTH);916917m_restart_interval = get_bits(16);918}919920// Read a start of scan (SOS) marker.921void jpeg_decoder::read_sos_marker()922{923uint num_left;924int i, ci, n, c, cc;925926num_left = get_bits(16);927928n = get_bits(8);929930m_comps_in_scan = n;931932num_left -= 3;933934if ((num_left != (uint)(n * 2 + 3)) || (n < 1) || (n > JPGD_MAX_COMPS_IN_SCAN))935stop_decoding(JPGD_BAD_SOS_LENGTH);936937for (i = 0; i < n; i++)938{939cc = get_bits(8);940c = get_bits(8);941num_left -= 2;942943for (ci = 0; ci < m_comps_in_frame; ci++)944if (cc == m_comp_ident[ci])945break;946947if (ci >= m_comps_in_frame)948stop_decoding(JPGD_BAD_SOS_COMP_ID);949950if (ci >= JPGD_MAX_COMPONENTS)951stop_decoding(JPGD_DECODE_ERROR);952953m_comp_list[i] = ci;954955m_comp_dc_tab[ci] = (c >> 4) & 15;956m_comp_ac_tab[ci] = (c & 15) + (JPGD_MAX_HUFF_TABLES >> 1);957958if (m_comp_dc_tab[ci] >= JPGD_MAX_HUFF_TABLES)959stop_decoding(JPGD_DECODE_ERROR);960961if (m_comp_ac_tab[ci] >= JPGD_MAX_HUFF_TABLES)962stop_decoding(JPGD_DECODE_ERROR);963}964965m_spectral_start = get_bits(8);966m_spectral_end = get_bits(8);967m_successive_high = get_bits(4);968m_successive_low = get_bits(4);969970if (!m_progressive_flag)971{972m_spectral_start = 0;973m_spectral_end = 63;974}975976num_left -= 3;977978/* read past whatever is num_left */979while (num_left)980{981get_bits(8);982num_left--;983}984}985986// Finds the next marker.987int jpeg_decoder::next_marker()988{989uint c, bytes;990991bytes = 0;992993do994{995do996{997bytes++;998c = get_bits(8);999} while (c != 0xFF);10001001do1002{1003c = get_bits(8);1004} while (c == 0xFF);10051006} while (c == 0);10071008// If bytes > 0 here, there where extra bytes before the marker (not good).10091010return c;1011}10121013// Process markers. Returns when an SOFx, SOI, EOI, or SOS marker is1014// encountered.1015int jpeg_decoder::process_markers()1016{1017int c;10181019for (; ; )1020{1021c = next_marker();10221023switch (c)1024{1025case M_SOF0:1026case M_SOF1:1027case M_SOF2:1028case M_SOF3:1029case M_SOF5:1030case M_SOF6:1031case M_SOF7:1032// case M_JPG:1033case M_SOF9:1034case M_SOF10:1035case M_SOF11:1036case M_SOF13:1037case M_SOF14:1038case M_SOF15:1039case M_SOI:1040case M_EOI:1041case M_SOS:1042{1043return c;1044}1045case M_DHT:1046{1047read_dht_marker();1048break;1049}1050// No arithmitic support - dumb patents!1051case M_DAC:1052{1053stop_decoding(JPGD_NO_ARITHMITIC_SUPPORT);1054break;1055}1056case M_DQT:1057{1058read_dqt_marker();1059break;1060}1061case M_DRI:1062{1063read_dri_marker();1064break;1065}1066//case M_APP0: /* no need to read the JFIF marker */1067case M_JPG:1068case M_RST0: /* no parameters */1069case M_RST1:1070case M_RST2:1071case M_RST3:1072case M_RST4:1073case M_RST5:1074case M_RST6:1075case M_RST7:1076case M_TEM:1077{1078stop_decoding(JPGD_UNEXPECTED_MARKER);1079break;1080}1081default: /* must be DNL, DHP, EXP, APPn, JPGn, COM, or RESn or APP0 */1082{1083skip_variable_marker();1084break;1085}1086}1087}1088}10891090// Finds the start of image (SOI) marker.1091void jpeg_decoder::locate_soi_marker()1092{1093uint lastchar, thischar;1094uint bytesleft;10951096lastchar = get_bits(8);10971098thischar = get_bits(8);10991100/* ok if it's a normal JPEG file without a special header */11011102if ((lastchar == 0xFF) && (thischar == M_SOI))1103return;11041105bytesleft = 4096;11061107for (; ; )1108{1109if (--bytesleft == 0)1110stop_decoding(JPGD_NOT_JPEG);11111112lastchar = thischar;11131114thischar = get_bits(8);11151116if (lastchar == 0xFF)1117{1118if (thischar == M_SOI)1119break;1120else if (thischar == M_EOI) // get_bits will keep returning M_EOI if we read past the end1121stop_decoding(JPGD_NOT_JPEG);1122}1123}11241125// 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.1126thischar = (m_bit_buf >> 24) & 0xFF;11271128if (thischar != 0xFF)1129stop_decoding(JPGD_NOT_JPEG);1130}11311132// Find a start of frame (SOF) marker.1133void jpeg_decoder::locate_sof_marker()1134{1135locate_soi_marker();11361137int c = process_markers();11381139switch (c)1140{1141case M_SOF2:1142{1143m_progressive_flag = JPGD_TRUE;1144read_sof_marker();1145break;1146}1147case M_SOF0: /* baseline DCT */1148case M_SOF1: /* extended sequential DCT */1149{1150read_sof_marker();1151break;1152}1153case M_SOF9: /* Arithmitic coding */1154{1155stop_decoding(JPGD_NO_ARITHMITIC_SUPPORT);1156break;1157}1158default:1159{1160stop_decoding(JPGD_UNSUPPORTED_MARKER);1161break;1162}1163}1164}11651166// Find a start of scan (SOS) marker.1167int jpeg_decoder::locate_sos_marker()1168{1169int c;11701171c = process_markers();11721173if (c == M_EOI)1174return JPGD_FALSE;1175else if (c != M_SOS)1176stop_decoding(JPGD_UNEXPECTED_MARKER);11771178read_sos_marker();11791180return JPGD_TRUE;1181}11821183// Reset everything to default/uninitialized state.1184void jpeg_decoder::init(jpeg_decoder_stream* pStream, uint32_t flags)1185{1186m_flags = flags;1187m_pMem_blocks = nullptr;1188m_error_code = JPGD_SUCCESS;1189m_ready_flag = false;1190m_image_x_size = m_image_y_size = 0;1191m_pStream = pStream;1192m_progressive_flag = JPGD_FALSE;11931194memset(m_huff_ac, 0, sizeof(m_huff_ac));1195memset(m_huff_num, 0, sizeof(m_huff_num));1196memset(m_huff_val, 0, sizeof(m_huff_val));1197memset(m_quant, 0, sizeof(m_quant));11981199m_scan_type = 0;1200m_comps_in_frame = 0;12011202memset(m_comp_h_samp, 0, sizeof(m_comp_h_samp));1203memset(m_comp_v_samp, 0, sizeof(m_comp_v_samp));1204memset(m_comp_quant, 0, sizeof(m_comp_quant));1205memset(m_comp_ident, 0, sizeof(m_comp_ident));1206memset(m_comp_h_blocks, 0, sizeof(m_comp_h_blocks));1207memset(m_comp_v_blocks, 0, sizeof(m_comp_v_blocks));12081209m_comps_in_scan = 0;1210memset(m_comp_list, 0, sizeof(m_comp_list));1211memset(m_comp_dc_tab, 0, sizeof(m_comp_dc_tab));1212memset(m_comp_ac_tab, 0, sizeof(m_comp_ac_tab));12131214m_spectral_start = 0;1215m_spectral_end = 0;1216m_successive_low = 0;1217m_successive_high = 0;1218m_max_mcu_x_size = 0;1219m_max_mcu_y_size = 0;1220m_blocks_per_mcu = 0;1221m_max_blocks_per_row = 0;1222m_mcus_per_row = 0;1223m_mcus_per_col = 0;12241225memset(m_mcu_org, 0, sizeof(m_mcu_org));12261227m_total_lines_left = 0;1228m_mcu_lines_left = 0;1229m_num_buffered_scanlines = 0;1230m_real_dest_bytes_per_scan_line = 0;1231m_dest_bytes_per_scan_line = 0;1232m_dest_bytes_per_pixel = 0;12331234memset(m_pHuff_tabs, 0, sizeof(m_pHuff_tabs));12351236memset(m_dc_coeffs, 0, sizeof(m_dc_coeffs));1237memset(m_ac_coeffs, 0, sizeof(m_ac_coeffs));1238memset(m_block_y_mcu, 0, sizeof(m_block_y_mcu));12391240m_eob_run = 0;12411242m_pIn_buf_ofs = m_in_buf;1243m_in_buf_left = 0;1244m_eof_flag = false;1245m_tem_flag = 0;12461247memset(m_in_buf_pad_start, 0, sizeof(m_in_buf_pad_start));1248memset(m_in_buf, 0, sizeof(m_in_buf));1249memset(m_in_buf_pad_end, 0, sizeof(m_in_buf_pad_end));12501251m_restart_interval = 0;1252m_restarts_left = 0;1253m_next_restart_num = 0;12541255m_max_mcus_per_row = 0;1256m_max_blocks_per_mcu = 0;1257m_max_mcus_per_col = 0;12581259memset(m_last_dc_val, 0, sizeof(m_last_dc_val));1260m_pMCU_coefficients = nullptr;1261m_pSample_buf = nullptr;1262m_pSample_buf_prev = nullptr;1263m_sample_buf_prev_valid = false;12641265m_total_bytes_read = 0;12661267m_pScan_line_0 = nullptr;1268m_pScan_line_1 = nullptr;12691270// Ready the input buffer.1271prep_in_buffer();12721273// Prime the bit buffer.1274m_bits_left = 16;1275m_bit_buf = 0;12761277get_bits(16);1278get_bits(16);12791280for (int i = 0; i < JPGD_MAX_BLOCKS_PER_MCU; i++)1281m_mcu_block_max_zag[i] = 64;12821283m_has_sse2 = false;12841285#if JPGD_USE_SSE21286#ifdef _MSC_VER1287int cpu_info[4];1288__cpuid(cpu_info, 1);1289const int cpu_info3 = cpu_info[3];1290m_has_sse2 = ((cpu_info3 >> 26U) & 1U) != 0U;1291#else1292m_has_sse2 = true;1293#endif1294#endif1295}12961297#define SCALEBITS 161298#define ONE_HALF ((int) 1 << (SCALEBITS-1))1299#define FIX(x) ((int) ((x) * (1L<<SCALEBITS) + 0.5f))13001301// Create a few tables that allow us to quickly convert YCbCr to RGB.1302void jpeg_decoder::create_look_ups()1303{1304for (int i = 0; i <= 255; i++)1305{1306int k = i - 128;1307m_crr[i] = (FIX(1.40200f) * k + ONE_HALF) >> SCALEBITS;1308m_cbb[i] = (FIX(1.77200f) * k + ONE_HALF) >> SCALEBITS;1309m_crg[i] = (-FIX(0.71414f)) * k;1310m_cbg[i] = (-FIX(0.34414f)) * k + ONE_HALF;1311}1312}13131314// This method throws back into the stream any bytes that where read1315// into the bit buffer during initial marker scanning.1316void jpeg_decoder::fix_in_buffer()1317{1318// In case any 0xFF's where pulled into the buffer during marker scanning.1319assert((m_bits_left & 7) == 0);13201321if (m_bits_left == 16)1322stuff_char((uint8)(m_bit_buf & 0xFF));13231324if (m_bits_left >= 8)1325stuff_char((uint8)((m_bit_buf >> 8) & 0xFF));13261327stuff_char((uint8)((m_bit_buf >> 16) & 0xFF));1328stuff_char((uint8)((m_bit_buf >> 24) & 0xFF));13291330m_bits_left = 16;1331get_bits_no_markers(16);1332get_bits_no_markers(16);1333}13341335void jpeg_decoder::transform_mcu(int mcu_row)1336{1337jpgd_block_coeff_t* pSrc_ptr = m_pMCU_coefficients;1338if (mcu_row * m_blocks_per_mcu >= m_max_blocks_per_row)1339stop_decoding(JPGD_DECODE_ERROR);13401341uint8* pDst_ptr = m_pSample_buf + mcu_row * m_blocks_per_mcu * 64;13421343for (int mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++)1344{1345idct(pSrc_ptr, pDst_ptr, m_mcu_block_max_zag[mcu_block], ((m_flags & cFlagDisableSIMD) == 0) && m_has_sse2);1346pSrc_ptr += 64;1347pDst_ptr += 64;1348}1349}13501351// Loads and dequantizes the next row of (already decoded) coefficients.1352// Progressive images only.1353void jpeg_decoder::load_next_row()1354{1355int i;1356jpgd_block_coeff_t* p;1357jpgd_quant_t* q;1358int mcu_row, mcu_block, row_block = 0;1359int component_num, component_id;1360int block_x_mcu[JPGD_MAX_COMPONENTS];13611362memset(block_x_mcu, 0, JPGD_MAX_COMPONENTS * sizeof(int));13631364for (mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++)1365{1366int block_x_mcu_ofs = 0, block_y_mcu_ofs = 0;13671368for (mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++)1369{1370component_id = m_mcu_org[mcu_block];1371if (m_comp_quant[component_id] >= JPGD_MAX_QUANT_TABLES)1372stop_decoding(JPGD_DECODE_ERROR);13731374q = m_quant[m_comp_quant[component_id]];13751376p = m_pMCU_coefficients + 64 * mcu_block;13771378jpgd_block_coeff_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);1379jpgd_block_coeff_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);1380p[0] = pDC[0];1381memcpy(&p[1], &pAC[1], 63 * sizeof(jpgd_block_coeff_t));13821383for (i = 63; i > 0; i--)1384if (p[g_ZAG[i]])1385break;13861387m_mcu_block_max_zag[mcu_block] = i + 1;13881389for (; i >= 0; i--)1390if (p[g_ZAG[i]])1391p[g_ZAG[i]] = static_cast<jpgd_block_coeff_t>(p[g_ZAG[i]] * q[i]);13921393row_block++;13941395if (m_comps_in_scan == 1)1396block_x_mcu[component_id]++;1397else1398{1399if (++block_x_mcu_ofs == m_comp_h_samp[component_id])1400{1401block_x_mcu_ofs = 0;14021403if (++block_y_mcu_ofs == m_comp_v_samp[component_id])1404{1405block_y_mcu_ofs = 0;14061407block_x_mcu[component_id] += m_comp_h_samp[component_id];1408}1409}1410}1411}14121413transform_mcu(mcu_row);1414}14151416if (m_comps_in_scan == 1)1417m_block_y_mcu[m_comp_list[0]]++;1418else1419{1420for (component_num = 0; component_num < m_comps_in_scan; component_num++)1421{1422component_id = m_comp_list[component_num];14231424m_block_y_mcu[component_id] += m_comp_v_samp[component_id];1425}1426}1427}14281429// Restart interval processing.1430void jpeg_decoder::process_restart()1431{1432int i;1433int c = 0;14341435// Align to a byte boundry1436// FIXME: Is this really necessary? get_bits_no_markers() never reads in markers!1437//get_bits_no_markers(m_bits_left & 7);14381439// Let's scan a little bit to find the marker, but not _too_ far.1440// 1536 is a "fudge factor" that determines how much to scan.1441for (i = 1536; i > 0; i--)1442if (get_char() == 0xFF)1443break;14441445if (i == 0)1446stop_decoding(JPGD_BAD_RESTART_MARKER);14471448for (; i > 0; i--)1449if ((c = get_char()) != 0xFF)1450break;14511452if (i == 0)1453stop_decoding(JPGD_BAD_RESTART_MARKER);14541455// Is it the expected marker? If not, something bad happened.1456if (c != (m_next_restart_num + M_RST0))1457stop_decoding(JPGD_BAD_RESTART_MARKER);14581459// Reset each component's DC prediction values.1460memset(&m_last_dc_val, 0, m_comps_in_frame * sizeof(uint));14611462m_eob_run = 0;14631464m_restarts_left = m_restart_interval;14651466m_next_restart_num = (m_next_restart_num + 1) & 7;14671468// Get the bit buffer going again...14691470m_bits_left = 16;1471get_bits_no_markers(16);1472get_bits_no_markers(16);1473}14741475static inline int dequantize_ac(int c, int q) { c *= q; return c; }14761477// Decodes and dequantizes the next row of coefficients.1478void jpeg_decoder::decode_next_row()1479{1480int row_block = 0;14811482for (int mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++)1483{1484if ((m_restart_interval) && (m_restarts_left == 0))1485process_restart();14861487jpgd_block_coeff_t* p = m_pMCU_coefficients;1488for (int mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++, p += 64)1489{1490int component_id = m_mcu_org[mcu_block];1491if (m_comp_quant[component_id] >= JPGD_MAX_QUANT_TABLES)1492stop_decoding(JPGD_DECODE_ERROR);14931494jpgd_quant_t* q = m_quant[m_comp_quant[component_id]];14951496int r, s;1497s = huff_decode(m_pHuff_tabs[m_comp_dc_tab[component_id]], r);1498if (s >= 16)1499stop_decoding(JPGD_DECODE_ERROR);15001501s = JPGD_HUFF_EXTEND(r, s);15021503m_last_dc_val[component_id] = (s += m_last_dc_val[component_id]);15041505p[0] = static_cast<jpgd_block_coeff_t>(s * q[0]);15061507int prev_num_set = m_mcu_block_max_zag[mcu_block];15081509huff_tables* pH = m_pHuff_tabs[m_comp_ac_tab[component_id]];15101511int k;1512for (k = 1; k < 64; k++)1513{1514int extra_bits;1515s = huff_decode(pH, extra_bits);15161517r = s >> 4;1518s &= 15;15191520if (s)1521{1522if (r)1523{1524if ((k + r) > 63)1525stop_decoding(JPGD_DECODE_ERROR);15261527if (k < prev_num_set)1528{1529int n = JPGD_MIN(r, prev_num_set - k);1530int kt = k;1531while (n--)1532p[g_ZAG[kt++]] = 0;1533}15341535k += r;1536}15371538s = JPGD_HUFF_EXTEND(extra_bits, s);15391540if (k >= 64)1541stop_decoding(JPGD_DECODE_ERROR);15421543p[g_ZAG[k]] = static_cast<jpgd_block_coeff_t>(dequantize_ac(s, q[k])); //s * q[k];1544}1545else1546{1547if (r == 15)1548{1549if ((k + 16) > 64)1550stop_decoding(JPGD_DECODE_ERROR);15511552if (k < prev_num_set)1553{1554int n = JPGD_MIN(16, prev_num_set - k);1555int kt = k;1556while (n--)1557{1558if (kt > 63)1559stop_decoding(JPGD_DECODE_ERROR);1560p[g_ZAG[kt++]] = 0;1561}1562}15631564k += 16 - 1; // - 1 because the loop counter is k15651566if (p[g_ZAG[k & 63]] != 0)1567stop_decoding(JPGD_DECODE_ERROR);1568}1569else1570break;1571}1572}15731574if (k < prev_num_set)1575{1576int kt = k;1577while (kt < prev_num_set)1578p[g_ZAG[kt++]] = 0;1579}15801581m_mcu_block_max_zag[mcu_block] = k;15821583row_block++;1584}15851586transform_mcu(mcu_row);15871588m_restarts_left--;1589}1590}15911592// YCbCr H1V1 (1x1:1:1, 3 m_blocks per MCU) to RGB1593void jpeg_decoder::H1V1Convert()1594{1595int row = m_max_mcu_y_size - m_mcu_lines_left;1596uint8* d = m_pScan_line_0;1597uint8* s = m_pSample_buf + row * 8;15981599for (int i = m_max_mcus_per_row; i > 0; i--)1600{1601for (int j = 0; j < 8; j++)1602{1603int y = s[j];1604int cb = s[64 + j];1605int cr = s[128 + j];16061607d[0] = clamp(y + m_crr[cr]);1608d[1] = clamp(y + ((m_crg[cr] + m_cbg[cb]) >> 16));1609d[2] = clamp(y + m_cbb[cb]);1610d[3] = 255;16111612d += 4;1613}16141615s += 64 * 3;1616}1617}16181619// YCbCr H2V1 (2x1:1:1, 4 m_blocks per MCU) to RGB1620void jpeg_decoder::H2V1Convert()1621{1622int row = m_max_mcu_y_size - m_mcu_lines_left;1623uint8* d0 = m_pScan_line_0;1624uint8* y = m_pSample_buf + row * 8;1625uint8* c = m_pSample_buf + 2 * 64 + row * 8;16261627for (int i = m_max_mcus_per_row; i > 0; i--)1628{1629for (int l = 0; l < 2; l++)1630{1631for (int j = 0; j < 4; j++)1632{1633int cb = c[0];1634int cr = c[64];16351636int rc = m_crr[cr];1637int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);1638int bc = m_cbb[cb];16391640int yy = y[j << 1];1641d0[0] = clamp(yy + rc);1642d0[1] = clamp(yy + gc);1643d0[2] = clamp(yy + bc);1644d0[3] = 255;16451646yy = y[(j << 1) + 1];1647d0[4] = clamp(yy + rc);1648d0[5] = clamp(yy + gc);1649d0[6] = clamp(yy + bc);1650d0[7] = 255;16511652d0 += 8;16531654c++;1655}1656y += 64;1657}16581659y += 64 * 4 - 64 * 2;1660c += 64 * 4 - 8;1661}1662}16631664// YCbCr H2V1 (2x1:1:1, 4 m_blocks per MCU) to RGB1665void jpeg_decoder::H2V1ConvertFiltered()1666{1667const uint BLOCKS_PER_MCU = 4;1668int row = m_max_mcu_y_size - m_mcu_lines_left;1669uint8* d0 = m_pScan_line_0;16701671const int half_image_x_size = (m_image_x_size >> 1) - 1;1672const int row_x8 = row * 8;16731674for (int x = 0; x < m_image_x_size; x++)1675{1676int y = m_pSample_buf[check_sample_buf_ofs((x >> 4) * BLOCKS_PER_MCU * 64 + ((x & 8) ? 64 : 0) + (x & 7) + row_x8)];16771678int c_x0 = (x - 1) >> 1;1679int c_x1 = JPGD_MIN(c_x0 + 1, half_image_x_size);1680c_x0 = JPGD_MAX(c_x0, 0);16811682int a = (c_x0 >> 3) * BLOCKS_PER_MCU * 64 + (c_x0 & 7) + row_x8 + 128;1683int cb0 = m_pSample_buf[check_sample_buf_ofs(a)];1684int cr0 = m_pSample_buf[check_sample_buf_ofs(a + 64)];16851686int b = (c_x1 >> 3) * BLOCKS_PER_MCU * 64 + (c_x1 & 7) + row_x8 + 128;1687int cb1 = m_pSample_buf[check_sample_buf_ofs(b)];1688int cr1 = m_pSample_buf[check_sample_buf_ofs(b + 64)];16891690int w0 = (x & 1) ? 3 : 1;1691int w1 = (x & 1) ? 1 : 3;16921693int cb = (cb0 * w0 + cb1 * w1 + 2) >> 2;1694int cr = (cr0 * w0 + cr1 * w1 + 2) >> 2;16951696int rc = m_crr[cr];1697int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);1698int bc = m_cbb[cb];16991700d0[0] = clamp(y + rc);1701d0[1] = clamp(y + gc);1702d0[2] = clamp(y + bc);1703d0[3] = 255;17041705d0 += 4;1706}1707}17081709// YCbCr H2V1 (1x2:1:1, 4 m_blocks per MCU) to RGB1710void jpeg_decoder::H1V2Convert()1711{1712int row = m_max_mcu_y_size - m_mcu_lines_left;1713uint8* d0 = m_pScan_line_0;1714uint8* d1 = m_pScan_line_1;1715uint8* y;1716uint8* c;17171718if (row < 8)1719y = m_pSample_buf + row * 8;1720else1721y = m_pSample_buf + 64 * 1 + (row & 7) * 8;17221723c = m_pSample_buf + 64 * 2 + (row >> 1) * 8;17241725for (int i = m_max_mcus_per_row; i > 0; i--)1726{1727for (int j = 0; j < 8; j++)1728{1729int cb = c[0 + j];1730int cr = c[64 + j];17311732int rc = m_crr[cr];1733int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);1734int bc = m_cbb[cb];17351736int yy = y[j];1737d0[0] = clamp(yy + rc);1738d0[1] = clamp(yy + gc);1739d0[2] = clamp(yy + bc);1740d0[3] = 255;17411742yy = y[8 + j];1743d1[0] = clamp(yy + rc);1744d1[1] = clamp(yy + gc);1745d1[2] = clamp(yy + bc);1746d1[3] = 255;17471748d0 += 4;1749d1 += 4;1750}17511752y += 64 * 4;1753c += 64 * 4;1754}1755}17561757// YCbCr H2V1 (1x2:1:1, 4 m_blocks per MCU) to RGB1758void jpeg_decoder::H1V2ConvertFiltered()1759{1760const uint BLOCKS_PER_MCU = 4;1761int y = m_image_y_size - m_total_lines_left;1762int row = y & 15;17631764const int half_image_y_size = (m_image_y_size >> 1) - 1;17651766uint8* d0 = m_pScan_line_0;17671768const int w0 = (row & 1) ? 3 : 1;1769const int w1 = (row & 1) ? 1 : 3;17701771int c_y0 = (y - 1) >> 1;1772int c_y1 = JPGD_MIN(c_y0 + 1, half_image_y_size);17731774const uint8_t* p_YSamples = m_pSample_buf;1775const uint8_t* p_C0Samples = m_pSample_buf;1776if ((c_y0 >= 0) && (((row & 15) == 0) || ((row & 15) == 15)) && (m_total_lines_left > 1))1777{1778assert(y > 0);1779assert(m_sample_buf_prev_valid);17801781if ((row & 15) == 15)1782p_YSamples = m_pSample_buf_prev;17831784p_C0Samples = m_pSample_buf_prev;1785}17861787const int y_sample_base_ofs = ((row & 8) ? 64 : 0) + (row & 7) * 8;1788const int y0_base = (c_y0 & 7) * 8 + 128;1789const int y1_base = (c_y1 & 7) * 8 + 128;17901791for (int x = 0; x < m_image_x_size; x++)1792{1793const int base_ofs = (x >> 3) * BLOCKS_PER_MCU * 64 + (x & 7);17941795int y_sample = p_YSamples[check_sample_buf_ofs(base_ofs + y_sample_base_ofs)];17961797int a = base_ofs + y0_base;1798int cb0_sample = p_C0Samples[check_sample_buf_ofs(a)];1799int cr0_sample = p_C0Samples[check_sample_buf_ofs(a + 64)];18001801int b = base_ofs + y1_base;1802int cb1_sample = m_pSample_buf[check_sample_buf_ofs(b)];1803int cr1_sample = m_pSample_buf[check_sample_buf_ofs(b + 64)];18041805int cb = (cb0_sample * w0 + cb1_sample * w1 + 2) >> 2;1806int cr = (cr0_sample * w0 + cr1_sample * w1 + 2) >> 2;18071808int rc = m_crr[cr];1809int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);1810int bc = m_cbb[cb];18111812d0[0] = clamp(y_sample + rc);1813d0[1] = clamp(y_sample + gc);1814d0[2] = clamp(y_sample + bc);1815d0[3] = 255;18161817d0 += 4;1818}1819}18201821// YCbCr H2V2 (2x2:1:1, 6 m_blocks per MCU) to RGB1822void jpeg_decoder::H2V2Convert()1823{1824int row = m_max_mcu_y_size - m_mcu_lines_left;1825uint8* d0 = m_pScan_line_0;1826uint8* d1 = m_pScan_line_1;1827uint8* y;1828uint8* c;18291830if (row < 8)1831y = m_pSample_buf + row * 8;1832else1833y = m_pSample_buf + 64 * 2 + (row & 7) * 8;18341835c = m_pSample_buf + 64 * 4 + (row >> 1) * 8;18361837for (int i = m_max_mcus_per_row; i > 0; i--)1838{1839for (int l = 0; l < 2; l++)1840{1841for (int j = 0; j < 8; j += 2)1842{1843int cb = c[0];1844int cr = c[64];18451846int rc = m_crr[cr];1847int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);1848int bc = m_cbb[cb];18491850int yy = y[j];1851d0[0] = clamp(yy + rc);1852d0[1] = clamp(yy + gc);1853d0[2] = clamp(yy + bc);1854d0[3] = 255;18551856yy = y[j + 1];1857d0[4] = clamp(yy + rc);1858d0[5] = clamp(yy + gc);1859d0[6] = clamp(yy + bc);1860d0[7] = 255;18611862yy = y[j + 8];1863d1[0] = clamp(yy + rc);1864d1[1] = clamp(yy + gc);1865d1[2] = clamp(yy + bc);1866d1[3] = 255;18671868yy = y[j + 8 + 1];1869d1[4] = clamp(yy + rc);1870d1[5] = clamp(yy + gc);1871d1[6] = clamp(yy + bc);1872d1[7] = 255;18731874d0 += 8;1875d1 += 8;18761877c++;1878}1879y += 64;1880}18811882y += 64 * 6 - 64 * 2;1883c += 64 * 6 - 8;1884}1885}18861887uint32_t jpeg_decoder::H2V2ConvertFiltered()1888{1889const uint BLOCKS_PER_MCU = 6;1890int y = m_image_y_size - m_total_lines_left;1891int row = y & 15;18921893const int half_image_y_size = (m_image_y_size >> 1) - 1;18941895uint8* d0 = m_pScan_line_0;18961897int c_y0 = (y - 1) >> 1;1898int c_y1 = JPGD_MIN(c_y0 + 1, half_image_y_size);18991900const uint8_t* p_YSamples = m_pSample_buf;1901const uint8_t* p_C0Samples = m_pSample_buf;1902if ((c_y0 >= 0) && (((row & 15) == 0) || ((row & 15) == 15)) && (m_total_lines_left > 1))1903{1904assert(y > 0);1905assert(m_sample_buf_prev_valid);19061907if ((row & 15) == 15)1908p_YSamples = m_pSample_buf_prev;19091910p_C0Samples = m_pSample_buf_prev;1911}19121913const int y_sample_base_ofs = ((row & 8) ? 128 : 0) + (row & 7) * 8;1914const int y0_base = (c_y0 & 7) * 8 + 256;1915const int y1_base = (c_y1 & 7) * 8 + 256;19161917const int half_image_x_size = (m_image_x_size >> 1) - 1;19181919static const uint8_t s_muls[2][2][4] =1920{1921{ { 1, 3, 3, 9 }, { 3, 9, 1, 3 }, },1922{ { 3, 1, 9, 3 }, { 9, 3, 3, 1 } }1923};19241925if (((row & 15) >= 1) && ((row & 15) <= 14))1926{1927assert((row & 1) == 1);1928assert(((y + 1 - 1) >> 1) == c_y0);19291930assert(p_YSamples == m_pSample_buf);1931assert(p_C0Samples == m_pSample_buf);19321933uint8* d1 = m_pScan_line_1;1934const int y_sample_base_ofs1 = (((row + 1) & 8) ? 128 : 0) + ((row + 1) & 7) * 8;19351936for (int x = 0; x < m_image_x_size; x++)1937{1938int k = (x >> 4) * BLOCKS_PER_MCU * 64 + ((x & 8) ? 64 : 0) + (x & 7);1939int y_sample0 = p_YSamples[check_sample_buf_ofs(k + y_sample_base_ofs)];1940int y_sample1 = p_YSamples[check_sample_buf_ofs(k + y_sample_base_ofs1)];19411942int c_x0 = (x - 1) >> 1;1943int c_x1 = JPGD_MIN(c_x0 + 1, half_image_x_size);1944c_x0 = JPGD_MAX(c_x0, 0);19451946int a = (c_x0 >> 3) * BLOCKS_PER_MCU * 64 + (c_x0 & 7);1947int cb00_sample = p_C0Samples[check_sample_buf_ofs(a + y0_base)];1948int cr00_sample = p_C0Samples[check_sample_buf_ofs(a + y0_base + 64)];19491950int cb01_sample = m_pSample_buf[check_sample_buf_ofs(a + y1_base)];1951int cr01_sample = m_pSample_buf[check_sample_buf_ofs(a + y1_base + 64)];19521953int b = (c_x1 >> 3) * BLOCKS_PER_MCU * 64 + (c_x1 & 7);1954int cb10_sample = p_C0Samples[check_sample_buf_ofs(b + y0_base)];1955int cr10_sample = p_C0Samples[check_sample_buf_ofs(b + y0_base + 64)];19561957int cb11_sample = m_pSample_buf[check_sample_buf_ofs(b + y1_base)];1958int cr11_sample = m_pSample_buf[check_sample_buf_ofs(b + y1_base + 64)];19591960{1961const uint8_t* pMuls = &s_muls[row & 1][x & 1][0];1962int cb = (cb00_sample * pMuls[0] + cb01_sample * pMuls[1] + cb10_sample * pMuls[2] + cb11_sample * pMuls[3] + 8) >> 4;1963int cr = (cr00_sample * pMuls[0] + cr01_sample * pMuls[1] + cr10_sample * pMuls[2] + cr11_sample * pMuls[3] + 8) >> 4;19641965int rc = m_crr[cr];1966int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);1967int bc = m_cbb[cb];19681969d0[0] = clamp(y_sample0 + rc);1970d0[1] = clamp(y_sample0 + gc);1971d0[2] = clamp(y_sample0 + bc);1972d0[3] = 255;19731974d0 += 4;1975}19761977{1978const uint8_t* pMuls = &s_muls[(row + 1) & 1][x & 1][0];1979int cb = (cb00_sample * pMuls[0] + cb01_sample * pMuls[1] + cb10_sample * pMuls[2] + cb11_sample * pMuls[3] + 8) >> 4;1980int cr = (cr00_sample * pMuls[0] + cr01_sample * pMuls[1] + cr10_sample * pMuls[2] + cr11_sample * pMuls[3] + 8) >> 4;19811982int rc = m_crr[cr];1983int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);1984int bc = m_cbb[cb];19851986d1[0] = clamp(y_sample1 + rc);1987d1[1] = clamp(y_sample1 + gc);1988d1[2] = clamp(y_sample1 + bc);1989d1[3] = 255;19901991d1 += 4;1992}19931994if (((x & 1) == 1) && (x < m_image_x_size - 1))1995{1996const int nx = x + 1;1997assert(c_x0 == (nx - 1) >> 1);19981999k = (nx >> 4) * BLOCKS_PER_MCU * 64 + ((nx & 8) ? 64 : 0) + (nx & 7);2000y_sample0 = p_YSamples[check_sample_buf_ofs(k + y_sample_base_ofs)];2001y_sample1 = p_YSamples[check_sample_buf_ofs(k + y_sample_base_ofs1)];20022003{2004const uint8_t* pMuls = &s_muls[row & 1][nx & 1][0];2005int cb = (cb00_sample * pMuls[0] + cb01_sample * pMuls[1] + cb10_sample * pMuls[2] + cb11_sample * pMuls[3] + 8) >> 4;2006int cr = (cr00_sample * pMuls[0] + cr01_sample * pMuls[1] + cr10_sample * pMuls[2] + cr11_sample * pMuls[3] + 8) >> 4;20072008int rc = m_crr[cr];2009int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);2010int bc = m_cbb[cb];20112012d0[0] = clamp(y_sample0 + rc);2013d0[1] = clamp(y_sample0 + gc);2014d0[2] = clamp(y_sample0 + bc);2015d0[3] = 255;20162017d0 += 4;2018}20192020{2021const uint8_t* pMuls = &s_muls[(row + 1) & 1][nx & 1][0];2022int cb = (cb00_sample * pMuls[0] + cb01_sample * pMuls[1] + cb10_sample * pMuls[2] + cb11_sample * pMuls[3] + 8) >> 4;2023int cr = (cr00_sample * pMuls[0] + cr01_sample * pMuls[1] + cr10_sample * pMuls[2] + cr11_sample * pMuls[3] + 8) >> 4;20242025int rc = m_crr[cr];2026int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);2027int bc = m_cbb[cb];20282029d1[0] = clamp(y_sample1 + rc);2030d1[1] = clamp(y_sample1 + gc);2031d1[2] = clamp(y_sample1 + bc);2032d1[3] = 255;20332034d1 += 4;2035}20362037++x;2038}2039}20402041return 2;2042}2043else2044{2045for (int x = 0; x < m_image_x_size; x++)2046{2047int y_sample = p_YSamples[check_sample_buf_ofs((x >> 4) * BLOCKS_PER_MCU * 64 + ((x & 8) ? 64 : 0) + (x & 7) + y_sample_base_ofs)];20482049int c_x0 = (x - 1) >> 1;2050int c_x1 = JPGD_MIN(c_x0 + 1, half_image_x_size);2051c_x0 = JPGD_MAX(c_x0, 0);20522053int a = (c_x0 >> 3) * BLOCKS_PER_MCU * 64 + (c_x0 & 7);2054int cb00_sample = p_C0Samples[check_sample_buf_ofs(a + y0_base)];2055int cr00_sample = p_C0Samples[check_sample_buf_ofs(a + y0_base + 64)];20562057int cb01_sample = m_pSample_buf[check_sample_buf_ofs(a + y1_base)];2058int cr01_sample = m_pSample_buf[check_sample_buf_ofs(a + y1_base + 64)];20592060int b = (c_x1 >> 3) * BLOCKS_PER_MCU * 64 + (c_x1 & 7);2061int cb10_sample = p_C0Samples[check_sample_buf_ofs(b + y0_base)];2062int cr10_sample = p_C0Samples[check_sample_buf_ofs(b + y0_base + 64)];20632064int cb11_sample = m_pSample_buf[check_sample_buf_ofs(b + y1_base)];2065int cr11_sample = m_pSample_buf[check_sample_buf_ofs(b + y1_base + 64)];20662067const uint8_t* pMuls = &s_muls[row & 1][x & 1][0];2068int cb = (cb00_sample * pMuls[0] + cb01_sample * pMuls[1] + cb10_sample * pMuls[2] + cb11_sample * pMuls[3] + 8) >> 4;2069int cr = (cr00_sample * pMuls[0] + cr01_sample * pMuls[1] + cr10_sample * pMuls[2] + cr11_sample * pMuls[3] + 8) >> 4;20702071int rc = m_crr[cr];2072int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);2073int bc = m_cbb[cb];20742075d0[0] = clamp(y_sample + rc);2076d0[1] = clamp(y_sample + gc);2077d0[2] = clamp(y_sample + bc);2078d0[3] = 255;20792080d0 += 4;2081}20822083return 1;2084}2085}20862087// Y (1 block per MCU) to 8-bit grayscale2088void jpeg_decoder::gray_convert()2089{2090int row = m_max_mcu_y_size - m_mcu_lines_left;2091uint8* d = m_pScan_line_0;2092uint8* s = m_pSample_buf + row * 8;20932094for (int i = m_max_mcus_per_row; i > 0; i--)2095{2096*(uint*)d = *(uint*)s;2097*(uint*)(&d[4]) = *(uint*)(&s[4]);20982099s += 64;2100d += 8;2101}2102}21032104// Find end of image (EOI) marker, so we can return to the user the exact size of the input stream.2105void jpeg_decoder::find_eoi()2106{2107if (!m_progressive_flag)2108{2109// Attempt to read the EOI marker.2110//get_bits_no_markers(m_bits_left & 7);21112112// Prime the bit buffer2113m_bits_left = 16;2114get_bits(16);2115get_bits(16);21162117// The next marker _should_ be EOI2118process_markers();2119}21202121m_total_bytes_read -= m_in_buf_left;2122}21232124int jpeg_decoder::decode_next_mcu_row()2125{2126if (::setjmp(m_jmp_state))2127return JPGD_FAILED;21282129const bool chroma_y_filtering = ((m_flags & cFlagBoxChromaFiltering) == 0) && ((m_scan_type == JPGD_YH2V2) || (m_scan_type == JPGD_YH1V2));2130if (chroma_y_filtering)2131{2132std::swap(m_pSample_buf, m_pSample_buf_prev);21332134m_sample_buf_prev_valid = true;2135}21362137if (m_progressive_flag)2138load_next_row();2139else2140decode_next_row();21412142// Find the EOI marker if that was the last row.2143if (m_total_lines_left <= m_max_mcu_y_size)2144find_eoi();21452146m_mcu_lines_left = m_max_mcu_y_size;2147return 0;2148}21492150int jpeg_decoder::decode(const void** pScan_line, uint* pScan_line_len)2151{2152if ((m_error_code) || (!m_ready_flag))2153return JPGD_FAILED;21542155if (m_total_lines_left == 0)2156return JPGD_DONE;21572158const bool chroma_y_filtering = ((m_flags & cFlagBoxChromaFiltering) == 0) && ((m_scan_type == JPGD_YH2V2) || (m_scan_type == JPGD_YH1V2));21592160bool get_another_mcu_row = false;2161bool got_mcu_early = false;2162if (chroma_y_filtering)2163{2164if (m_total_lines_left == m_image_y_size)2165get_another_mcu_row = true;2166else if ((m_mcu_lines_left == 1) && (m_total_lines_left > 1))2167{2168get_another_mcu_row = true;2169got_mcu_early = true;2170}2171}2172else2173{2174get_another_mcu_row = (m_mcu_lines_left == 0);2175}21762177if (get_another_mcu_row)2178{2179int status = decode_next_mcu_row();2180if (status != 0)2181return status;2182}21832184switch (m_scan_type)2185{2186case JPGD_YH2V2:2187{2188if ((m_flags & cFlagBoxChromaFiltering) == 0)2189{2190if (m_num_buffered_scanlines == 1)2191{2192*pScan_line = m_pScan_line_1;2193}2194else if (m_num_buffered_scanlines == 0)2195{2196m_num_buffered_scanlines = H2V2ConvertFiltered();2197*pScan_line = m_pScan_line_0;2198}21992200m_num_buffered_scanlines--;2201}2202else2203{2204if ((m_mcu_lines_left & 1) == 0)2205{2206H2V2Convert();2207*pScan_line = m_pScan_line_0;2208}2209else2210*pScan_line = m_pScan_line_1;2211}22122213break;2214}2215case JPGD_YH2V1:2216{2217if ((m_flags & cFlagBoxChromaFiltering) == 0)2218H2V1ConvertFiltered();2219else2220H2V1Convert();2221*pScan_line = m_pScan_line_0;2222break;2223}2224case JPGD_YH1V2:2225{2226if (chroma_y_filtering)2227{2228H1V2ConvertFiltered();2229*pScan_line = m_pScan_line_0;2230}2231else2232{2233if ((m_mcu_lines_left & 1) == 0)2234{2235H1V2Convert();2236*pScan_line = m_pScan_line_0;2237}2238else2239*pScan_line = m_pScan_line_1;2240}22412242break;2243}2244case JPGD_YH1V1:2245{2246H1V1Convert();2247*pScan_line = m_pScan_line_0;2248break;2249}2250case JPGD_GRAYSCALE:2251{2252gray_convert();2253*pScan_line = m_pScan_line_0;22542255break;2256}2257}22582259*pScan_line_len = m_real_dest_bytes_per_scan_line;22602261if (!got_mcu_early)2262{2263m_mcu_lines_left--;2264}22652266m_total_lines_left--;22672268return JPGD_SUCCESS;2269}22702271// Creates the tables needed for efficient Huffman decoding.2272void jpeg_decoder::make_huff_table(int index, huff_tables* pH)2273{2274int p, i, l, si;2275uint8 huffsize[258];2276uint huffcode[258];2277uint code;2278uint subtree;2279int code_size;2280int lastp;2281int nextfreeentry;2282int currententry;22832284pH->ac_table = m_huff_ac[index] != 0;22852286p = 0;22872288for (l = 1; l <= 16; l++)2289{2290for (i = 1; i <= m_huff_num[index][l]; i++)2291{2292if (p >= 257)2293stop_decoding(JPGD_DECODE_ERROR);2294huffsize[p++] = static_cast<uint8>(l);2295}2296}22972298assert(p < 258);2299huffsize[p] = 0;23002301lastp = p;23022303code = 0;2304si = huffsize[0];2305p = 0;23062307while (huffsize[p])2308{2309while (huffsize[p] == si)2310{2311if (p >= 257)2312stop_decoding(JPGD_DECODE_ERROR);2313huffcode[p++] = code;2314code++;2315}23162317code <<= 1;2318si++;2319}23202321memset(pH->look_up, 0, sizeof(pH->look_up));2322memset(pH->look_up2, 0, sizeof(pH->look_up2));2323memset(pH->tree, 0, sizeof(pH->tree));2324memset(pH->code_size, 0, sizeof(pH->code_size));23252326nextfreeentry = -1;23272328p = 0;23292330while (p < lastp)2331{2332i = m_huff_val[index][p];23332334code = huffcode[p];2335code_size = huffsize[p];23362337assert(i < JPGD_HUFF_CODE_SIZE_MAX_LENGTH);2338pH->code_size[i] = static_cast<uint8>(code_size);23392340if (code_size <= 8)2341{2342code <<= (8 - code_size);23432344for (l = 1 << (8 - code_size); l > 0; l--)2345{2346if (code >= 256)2347stop_decoding(JPGD_DECODE_ERROR);23482349pH->look_up[code] = i;23502351bool has_extrabits = false;2352int extra_bits = 0;2353int num_extra_bits = i & 15;23542355int bits_to_fetch = code_size;2356if (num_extra_bits)2357{2358int total_codesize = code_size + num_extra_bits;2359if (total_codesize <= 8)2360{2361has_extrabits = true;2362extra_bits = ((1 << num_extra_bits) - 1) & (code >> (8 - total_codesize));23632364if (extra_bits > 0x7FFF)2365stop_decoding(JPGD_DECODE_ERROR);23662367bits_to_fetch += num_extra_bits;2368}2369}23702371if (!has_extrabits)2372pH->look_up2[code] = i | (bits_to_fetch << 8);2373else2374pH->look_up2[code] = i | 0x8000 | (extra_bits << 16) | (bits_to_fetch << 8);23752376code++;2377}2378}2379else2380{2381subtree = (code >> (code_size - 8)) & 0xFF;23822383currententry = pH->look_up[subtree];23842385if (currententry == 0)2386{2387pH->look_up[subtree] = currententry = nextfreeentry;2388pH->look_up2[subtree] = currententry = nextfreeentry;23892390nextfreeentry -= 2;2391}23922393code <<= (16 - (code_size - 8));23942395for (l = code_size; l > 9; l--)2396{2397if ((code & 0x8000) == 0)2398currententry--;23992400unsigned int idx = -currententry - 1;24012402if (idx >= JPGD_HUFF_TREE_MAX_LENGTH)2403stop_decoding(JPGD_DECODE_ERROR);24042405if (pH->tree[idx] == 0)2406{2407pH->tree[idx] = nextfreeentry;24082409currententry = nextfreeentry;24102411nextfreeentry -= 2;2412}2413else2414{2415currententry = pH->tree[idx];2416}24172418code <<= 1;2419}24202421if ((code & 0x8000) == 0)2422currententry--;24232424if ((-currententry - 1) >= JPGD_HUFF_TREE_MAX_LENGTH)2425stop_decoding(JPGD_DECODE_ERROR);24262427pH->tree[-currententry - 1] = i;2428}24292430p++;2431}2432}24332434// Verifies the quantization tables needed for this scan are available.2435void jpeg_decoder::check_quant_tables()2436{2437for (int i = 0; i < m_comps_in_scan; i++)2438if (m_quant[m_comp_quant[m_comp_list[i]]] == nullptr)2439stop_decoding(JPGD_UNDEFINED_QUANT_TABLE);2440}24412442// Verifies that all the Huffman tables needed for this scan are available.2443void jpeg_decoder::check_huff_tables()2444{2445for (int i = 0; i < m_comps_in_scan; i++)2446{2447if ((m_spectral_start == 0) && (m_huff_num[m_comp_dc_tab[m_comp_list[i]]] == nullptr))2448stop_decoding(JPGD_UNDEFINED_HUFF_TABLE);24492450if ((m_spectral_end > 0) && (m_huff_num[m_comp_ac_tab[m_comp_list[i]]] == nullptr))2451stop_decoding(JPGD_UNDEFINED_HUFF_TABLE);2452}24532454for (int i = 0; i < JPGD_MAX_HUFF_TABLES; i++)2455if (m_huff_num[i])2456{2457if (!m_pHuff_tabs[i])2458m_pHuff_tabs[i] = (huff_tables*)alloc(sizeof(huff_tables));24592460make_huff_table(i, m_pHuff_tabs[i]);2461}2462}24632464// Determines the component order inside each MCU.2465// Also calcs how many MCU's are on each row, etc.2466bool jpeg_decoder::calc_mcu_block_order()2467{2468int component_num, component_id;2469int max_h_samp = 0, max_v_samp = 0;24702471for (component_id = 0; component_id < m_comps_in_frame; component_id++)2472{2473if (m_comp_h_samp[component_id] > max_h_samp)2474max_h_samp = m_comp_h_samp[component_id];24752476if (m_comp_v_samp[component_id] > max_v_samp)2477max_v_samp = m_comp_v_samp[component_id];2478}24792480for (component_id = 0; component_id < m_comps_in_frame; component_id++)2481{2482m_comp_h_blocks[component_id] = ((((m_image_x_size * m_comp_h_samp[component_id]) + (max_h_samp - 1)) / max_h_samp) + 7) / 8;2483m_comp_v_blocks[component_id] = ((((m_image_y_size * m_comp_v_samp[component_id]) + (max_v_samp - 1)) / max_v_samp) + 7) / 8;2484}24852486if (m_comps_in_scan == 1)2487{2488m_mcus_per_row = m_comp_h_blocks[m_comp_list[0]];2489m_mcus_per_col = m_comp_v_blocks[m_comp_list[0]];2490}2491else2492{2493m_mcus_per_row = (((m_image_x_size + 7) / 8) + (max_h_samp - 1)) / max_h_samp;2494m_mcus_per_col = (((m_image_y_size + 7) / 8) + (max_v_samp - 1)) / max_v_samp;2495}24962497if (m_comps_in_scan == 1)2498{2499m_mcu_org[0] = m_comp_list[0];25002501m_blocks_per_mcu = 1;2502}2503else2504{2505m_blocks_per_mcu = 0;25062507for (component_num = 0; component_num < m_comps_in_scan; component_num++)2508{2509int num_blocks;25102511component_id = m_comp_list[component_num];25122513num_blocks = m_comp_h_samp[component_id] * m_comp_v_samp[component_id];25142515while (num_blocks--)2516m_mcu_org[m_blocks_per_mcu++] = component_id;2517}2518}25192520if (m_blocks_per_mcu > m_max_blocks_per_mcu)2521return false;25222523for (int mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++)2524{2525int comp_id = m_mcu_org[mcu_block];2526if (comp_id >= JPGD_MAX_QUANT_TABLES)2527return false;2528}25292530return true;2531}25322533// Starts a new scan.2534int jpeg_decoder::init_scan()2535{2536if (!locate_sos_marker())2537return JPGD_FALSE;25382539if (!calc_mcu_block_order())2540return JPGD_FALSE;25412542check_huff_tables();25432544check_quant_tables();25452546memset(m_last_dc_val, 0, m_comps_in_frame * sizeof(uint));25472548m_eob_run = 0;25492550if (m_restart_interval)2551{2552m_restarts_left = m_restart_interval;2553m_next_restart_num = 0;2554}25552556fix_in_buffer();25572558return JPGD_TRUE;2559}25602561// Starts a frame. Determines if the number of components or sampling factors2562// are supported.2563void jpeg_decoder::init_frame()2564{2565int i;25662567if (m_comps_in_frame == 1)2568{2569if ((m_comp_h_samp[0] != 1) || (m_comp_v_samp[0] != 1))2570stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS);25712572m_scan_type = JPGD_GRAYSCALE;2573m_max_blocks_per_mcu = 1;2574m_max_mcu_x_size = 8;2575m_max_mcu_y_size = 8;2576}2577else if (m_comps_in_frame == 3)2578{2579if (((m_comp_h_samp[1] != 1) || (m_comp_v_samp[1] != 1)) ||2580((m_comp_h_samp[2] != 1) || (m_comp_v_samp[2] != 1)))2581stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS);25822583if ((m_comp_h_samp[0] == 1) && (m_comp_v_samp[0] == 1))2584{2585m_scan_type = JPGD_YH1V1;25862587m_max_blocks_per_mcu = 3;2588m_max_mcu_x_size = 8;2589m_max_mcu_y_size = 8;2590}2591else if ((m_comp_h_samp[0] == 2) && (m_comp_v_samp[0] == 1))2592{2593m_scan_type = JPGD_YH2V1;2594m_max_blocks_per_mcu = 4;2595m_max_mcu_x_size = 16;2596m_max_mcu_y_size = 8;2597}2598else if ((m_comp_h_samp[0] == 1) && (m_comp_v_samp[0] == 2))2599{2600m_scan_type = JPGD_YH1V2;2601m_max_blocks_per_mcu = 4;2602m_max_mcu_x_size = 8;2603m_max_mcu_y_size = 16;2604}2605else if ((m_comp_h_samp[0] == 2) && (m_comp_v_samp[0] == 2))2606{2607m_scan_type = JPGD_YH2V2;2608m_max_blocks_per_mcu = 6;2609m_max_mcu_x_size = 16;2610m_max_mcu_y_size = 16;2611}2612else2613stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS);2614}2615else2616stop_decoding(JPGD_UNSUPPORTED_COLORSPACE);26172618m_max_mcus_per_row = (m_image_x_size + (m_max_mcu_x_size - 1)) / m_max_mcu_x_size;2619m_max_mcus_per_col = (m_image_y_size + (m_max_mcu_y_size - 1)) / m_max_mcu_y_size;26202621// These values are for the *destination* pixels: after conversion.2622if (m_scan_type == JPGD_GRAYSCALE)2623m_dest_bytes_per_pixel = 1;2624else2625m_dest_bytes_per_pixel = 4;26262627m_dest_bytes_per_scan_line = ((m_image_x_size + 15) & 0xFFF0) * m_dest_bytes_per_pixel;26282629m_real_dest_bytes_per_scan_line = (m_image_x_size * m_dest_bytes_per_pixel);26302631// Initialize two scan line buffers.2632m_pScan_line_0 = (uint8*)alloc_aligned(m_dest_bytes_per_scan_line, true);2633if ((m_scan_type == JPGD_YH1V2) || (m_scan_type == JPGD_YH2V2))2634m_pScan_line_1 = (uint8*)alloc_aligned(m_dest_bytes_per_scan_line, true);26352636m_max_blocks_per_row = m_max_mcus_per_row * m_max_blocks_per_mcu;26372638// Should never happen2639if (m_max_blocks_per_row > JPGD_MAX_BLOCKS_PER_ROW)2640stop_decoding(JPGD_DECODE_ERROR);26412642// Allocate the coefficient buffer, enough for one MCU2643m_pMCU_coefficients = (jpgd_block_coeff_t *)alloc_aligned(m_max_blocks_per_mcu * 64 * sizeof(jpgd_block_coeff_t));26442645for (i = 0; i < m_max_blocks_per_mcu; i++)2646m_mcu_block_max_zag[i] = 64;26472648m_pSample_buf = (uint8*)alloc_aligned(m_max_blocks_per_row * 64);2649m_pSample_buf_prev = (uint8*)alloc_aligned(m_max_blocks_per_row * 64);26502651m_total_lines_left = m_image_y_size;26522653m_mcu_lines_left = 0;26542655create_look_ups();2656}26572658// The coeff_buf series of methods originally stored the coefficients2659// into a "virtual" file which was located in EMS, XMS, or a disk file. A cache2660// was used to make this process more efficient. Now, we can store the entire2661// thing in RAM.2662jpeg_decoder::coeff_buf* jpeg_decoder::coeff_buf_open(int block_num_x, int block_num_y, int block_len_x, int block_len_y)2663{2664coeff_buf* cb = (coeff_buf*)alloc(sizeof(coeff_buf));26652666cb->block_num_x = block_num_x;2667cb->block_num_y = block_num_y;2668cb->block_len_x = block_len_x;2669cb->block_len_y = block_len_y;2670cb->block_size = (block_len_x * block_len_y) * sizeof(jpgd_block_coeff_t);2671cb->pData = (uint8*)alloc(cb->block_size * block_num_x * block_num_y, true);2672return cb;2673}26742675inline jpgd_block_coeff_t* jpeg_decoder::coeff_buf_getp(coeff_buf* cb, int block_x, int block_y)2676{2677if ((block_x >= cb->block_num_x) || (block_y >= cb->block_num_y))2678stop_decoding(JPGD_DECODE_ERROR);26792680return (jpgd_block_coeff_t*)(cb->pData + block_x * cb->block_size + block_y * (cb->block_size * cb->block_num_x));2681}26822683// The following methods decode the various types of m_blocks encountered2684// in progressively encoded images.2685void jpeg_decoder::decode_block_dc_first(jpeg_decoder* pD, int component_id, int block_x, int block_y)2686{2687int s, r;2688jpgd_block_coeff_t* p = pD->coeff_buf_getp(pD->m_dc_coeffs[component_id], block_x, block_y);26892690if ((s = pD->huff_decode(pD->m_pHuff_tabs[pD->m_comp_dc_tab[component_id]])) != 0)2691{2692if (s >= 16)2693pD->stop_decoding(JPGD_DECODE_ERROR);26942695r = pD->get_bits_no_markers(s);2696s = JPGD_HUFF_EXTEND(r, s);2697}26982699pD->m_last_dc_val[component_id] = (s += pD->m_last_dc_val[component_id]);27002701p[0] = static_cast<jpgd_block_coeff_t>(s << pD->m_successive_low);2702}27032704void jpeg_decoder::decode_block_dc_refine(jpeg_decoder* pD, int component_id, int block_x, int block_y)2705{2706if (pD->get_bits_no_markers(1))2707{2708jpgd_block_coeff_t* p = pD->coeff_buf_getp(pD->m_dc_coeffs[component_id], block_x, block_y);27092710p[0] |= (1 << pD->m_successive_low);2711}2712}27132714void jpeg_decoder::decode_block_ac_first(jpeg_decoder* pD, int component_id, int block_x, int block_y)2715{2716int k, s, r;27172718if (pD->m_eob_run)2719{2720pD->m_eob_run--;2721return;2722}27232724jpgd_block_coeff_t* p = pD->coeff_buf_getp(pD->m_ac_coeffs[component_id], block_x, block_y);27252726for (k = pD->m_spectral_start; k <= pD->m_spectral_end; k++)2727{2728unsigned int idx = pD->m_comp_ac_tab[component_id];2729if (idx >= JPGD_MAX_HUFF_TABLES)2730pD->stop_decoding(JPGD_DECODE_ERROR);27312732s = pD->huff_decode(pD->m_pHuff_tabs[idx]);27332734r = s >> 4;2735s &= 15;27362737if (s)2738{2739if ((k += r) > 63)2740pD->stop_decoding(JPGD_DECODE_ERROR);27412742r = pD->get_bits_no_markers(s);2743s = JPGD_HUFF_EXTEND(r, s);27442745p[g_ZAG[k]] = static_cast<jpgd_block_coeff_t>(s << pD->m_successive_low);2746}2747else2748{2749if (r == 15)2750{2751if ((k += 15) > 63)2752pD->stop_decoding(JPGD_DECODE_ERROR);2753}2754else2755{2756pD->m_eob_run = 1 << r;27572758if (r)2759pD->m_eob_run += pD->get_bits_no_markers(r);27602761pD->m_eob_run--;27622763break;2764}2765}2766}2767}27682769void jpeg_decoder::decode_block_ac_refine(jpeg_decoder* pD, int component_id, int block_x, int block_y)2770{2771int s, k, r;27722773int p1 = 1 << pD->m_successive_low;27742775//int m1 = (-1) << pD->m_successive_low;2776int m1 = static_cast<int>((UINT32_MAX << pD->m_successive_low));27772778jpgd_block_coeff_t* p = pD->coeff_buf_getp(pD->m_ac_coeffs[component_id], block_x, block_y);2779if (pD->m_spectral_end > 63)2780pD->stop_decoding(JPGD_DECODE_ERROR);27812782k = pD->m_spectral_start;27832784if (pD->m_eob_run == 0)2785{2786for (; k <= pD->m_spectral_end; k++)2787{2788unsigned int idx = pD->m_comp_ac_tab[component_id];2789if (idx >= JPGD_MAX_HUFF_TABLES)2790pD->stop_decoding(JPGD_DECODE_ERROR);27912792s = pD->huff_decode(pD->m_pHuff_tabs[idx]);27932794r = s >> 4;2795s &= 15;27962797if (s)2798{2799if (s != 1)2800pD->stop_decoding(JPGD_DECODE_ERROR);28012802if (pD->get_bits_no_markers(1))2803s = p1;2804else2805s = m1;2806}2807else2808{2809if (r != 15)2810{2811pD->m_eob_run = 1 << r;28122813if (r)2814pD->m_eob_run += pD->get_bits_no_markers(r);28152816break;2817}2818}28192820do2821{2822jpgd_block_coeff_t* this_coef = p + g_ZAG[k & 63];28232824if (*this_coef != 0)2825{2826if (pD->get_bits_no_markers(1))2827{2828if ((*this_coef & p1) == 0)2829{2830if (*this_coef >= 0)2831*this_coef = static_cast<jpgd_block_coeff_t>(*this_coef + p1);2832else2833*this_coef = static_cast<jpgd_block_coeff_t>(*this_coef + m1);2834}2835}2836}2837else2838{2839if (--r < 0)2840break;2841}28422843k++;28442845} while (k <= pD->m_spectral_end);28462847if ((s) && (k < 64))2848{2849p[g_ZAG[k]] = static_cast<jpgd_block_coeff_t>(s);2850}2851}2852}28532854if (pD->m_eob_run > 0)2855{2856for (; k <= pD->m_spectral_end; k++)2857{2858jpgd_block_coeff_t* this_coef = p + g_ZAG[k & 63]; // logical AND to shut up static code analysis28592860if (*this_coef != 0)2861{2862if (pD->get_bits_no_markers(1))2863{2864if ((*this_coef & p1) == 0)2865{2866if (*this_coef >= 0)2867*this_coef = static_cast<jpgd_block_coeff_t>(*this_coef + p1);2868else2869*this_coef = static_cast<jpgd_block_coeff_t>(*this_coef + m1);2870}2871}2872}2873}28742875pD->m_eob_run--;2876}2877}28782879// Decode a scan in a progressively encoded image.2880void jpeg_decoder::decode_scan(pDecode_block_func decode_block_func)2881{2882int mcu_row, mcu_col, mcu_block;2883int block_x_mcu[JPGD_MAX_COMPONENTS], block_y_mcu[JPGD_MAX_COMPONENTS];28842885memset(block_y_mcu, 0, sizeof(block_y_mcu));28862887for (mcu_col = 0; mcu_col < m_mcus_per_col; mcu_col++)2888{2889int component_num, component_id;28902891memset(block_x_mcu, 0, sizeof(block_x_mcu));28922893for (mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++)2894{2895int block_x_mcu_ofs = 0, block_y_mcu_ofs = 0;28962897if ((m_restart_interval) && (m_restarts_left == 0))2898process_restart();28992900for (mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++)2901{2902component_id = m_mcu_org[mcu_block];29032904decode_block_func(this, component_id, block_x_mcu[component_id] + block_x_mcu_ofs, block_y_mcu[component_id] + block_y_mcu_ofs);29052906if (m_comps_in_scan == 1)2907block_x_mcu[component_id]++;2908else2909{2910if (++block_x_mcu_ofs == m_comp_h_samp[component_id])2911{2912block_x_mcu_ofs = 0;29132914if (++block_y_mcu_ofs == m_comp_v_samp[component_id])2915{2916block_y_mcu_ofs = 0;2917block_x_mcu[component_id] += m_comp_h_samp[component_id];2918}2919}2920}2921}29222923m_restarts_left--;2924}29252926if (m_comps_in_scan == 1)2927block_y_mcu[m_comp_list[0]]++;2928else2929{2930for (component_num = 0; component_num < m_comps_in_scan; component_num++)2931{2932component_id = m_comp_list[component_num];2933block_y_mcu[component_id] += m_comp_v_samp[component_id];2934}2935}2936}2937}29382939// Decode a progressively encoded image.2940void jpeg_decoder::init_progressive()2941{2942int i;29432944if (m_comps_in_frame == 4)2945stop_decoding(JPGD_UNSUPPORTED_COLORSPACE);29462947// Allocate the coefficient buffers.2948for (i = 0; i < m_comps_in_frame; i++)2949{2950m_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);2951m_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);2952}29532954// See https://libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf2955uint32_t total_scans = 0;2956const uint32_t MAX_SCANS_TO_PROCESS = 1000;29572958for (; ; )2959{2960int dc_only_scan, refinement_scan;2961pDecode_block_func decode_block_func;29622963if (!init_scan())2964break;29652966dc_only_scan = (m_spectral_start == 0);2967refinement_scan = (m_successive_high != 0);29682969if ((m_spectral_start > m_spectral_end) || (m_spectral_end > 63))2970stop_decoding(JPGD_BAD_SOS_SPECTRAL);29712972if (dc_only_scan)2973{2974if (m_spectral_end)2975stop_decoding(JPGD_BAD_SOS_SPECTRAL);2976}2977else if (m_comps_in_scan != 1) /* AC scans can only contain one component */2978stop_decoding(JPGD_BAD_SOS_SPECTRAL);29792980if ((refinement_scan) && (m_successive_low != m_successive_high - 1))2981stop_decoding(JPGD_BAD_SOS_SUCCESSIVE);29822983if (dc_only_scan)2984{2985if (refinement_scan)2986decode_block_func = decode_block_dc_refine;2987else2988decode_block_func = decode_block_dc_first;2989}2990else2991{2992if (refinement_scan)2993decode_block_func = decode_block_ac_refine;2994else2995decode_block_func = decode_block_ac_first;2996}29972998decode_scan(decode_block_func);29993000m_bits_left = 16;3001get_bits(16);3002get_bits(16);30033004total_scans++;3005if (total_scans > MAX_SCANS_TO_PROCESS)3006stop_decoding(JPGD_TOO_MANY_SCANS);3007}30083009m_comps_in_scan = m_comps_in_frame;30103011for (i = 0; i < m_comps_in_frame; i++)3012m_comp_list[i] = i;30133014if (!calc_mcu_block_order())3015stop_decoding(JPGD_DECODE_ERROR);3016}30173018void jpeg_decoder::init_sequential()3019{3020if (!init_scan())3021stop_decoding(JPGD_UNEXPECTED_MARKER);3022}30233024void jpeg_decoder::decode_start()3025{3026init_frame();30273028if (m_progressive_flag)3029init_progressive();3030else3031init_sequential();3032}30333034void jpeg_decoder::decode_init(jpeg_decoder_stream* pStream, uint32_t flags)3035{3036init(pStream, flags);3037locate_sof_marker();3038}30393040jpeg_decoder::jpeg_decoder(jpeg_decoder_stream* pStream, uint32_t flags)3041{3042if (::setjmp(m_jmp_state))3043return;3044decode_init(pStream, flags);3045}30463047int jpeg_decoder::begin_decoding()3048{3049if (m_ready_flag)3050return JPGD_SUCCESS;30513052if (m_error_code)3053return JPGD_FAILED;30543055if (::setjmp(m_jmp_state))3056return JPGD_FAILED;30573058decode_start();30593060m_ready_flag = true;30613062return JPGD_SUCCESS;3063}30643065jpeg_decoder::~jpeg_decoder()3066{3067free_all_blocks();3068}30693070jpeg_decoder_file_stream::jpeg_decoder_file_stream()3071{3072m_pFile = nullptr;3073m_eof_flag = false;3074m_error_flag = false;3075}30763077void jpeg_decoder_file_stream::close()3078{3079if (m_pFile)3080{3081fclose(m_pFile);3082m_pFile = nullptr;3083}30843085m_eof_flag = false;3086m_error_flag = false;3087}30883089jpeg_decoder_file_stream::~jpeg_decoder_file_stream()3090{3091close();3092}30933094bool jpeg_decoder_file_stream::open(const char* Pfilename)3095{3096close();30973098m_eof_flag = false;3099m_error_flag = false;31003101#if defined(_MSC_VER)3102m_pFile = nullptr;3103fopen_s(&m_pFile, Pfilename, "rb");3104#else3105m_pFile = fopen(Pfilename, "rb");3106#endif3107return m_pFile != nullptr;3108}31093110int jpeg_decoder_file_stream::read(uint8* pBuf, int max_bytes_to_read, bool* pEOF_flag)3111{3112if (!m_pFile)3113return -1;31143115if (m_eof_flag)3116{3117*pEOF_flag = true;3118return 0;3119}31203121if (m_error_flag)3122return -1;31233124int bytes_read = static_cast<int>(fread(pBuf, 1, max_bytes_to_read, m_pFile));3125if (bytes_read < max_bytes_to_read)3126{3127if (ferror(m_pFile))3128{3129m_error_flag = true;3130return -1;3131}31323133m_eof_flag = true;3134*pEOF_flag = true;3135}31363137return bytes_read;3138}31393140bool jpeg_decoder_mem_stream::open(const uint8* pSrc_data, uint size)3141{3142close();3143m_pSrc_data = pSrc_data;3144m_ofs = 0;3145m_size = size;3146return true;3147}31483149int jpeg_decoder_mem_stream::read(uint8* pBuf, int max_bytes_to_read, bool* pEOF_flag)3150{3151*pEOF_flag = false;31523153if (!m_pSrc_data)3154return -1;31553156uint bytes_remaining = m_size - m_ofs;3157if ((uint)max_bytes_to_read > bytes_remaining)3158{3159max_bytes_to_read = bytes_remaining;3160*pEOF_flag = true;3161}31623163memcpy(pBuf, m_pSrc_data + m_ofs, max_bytes_to_read);3164m_ofs += max_bytes_to_read;31653166return max_bytes_to_read;3167}31683169unsigned char* decompress_jpeg_image_from_stream(jpeg_decoder_stream* pStream, int* width, int* height, int* actual_comps, int req_comps, uint32_t flags)3170{3171if (!actual_comps)3172return nullptr;3173*actual_comps = 0;31743175if ((!pStream) || (!width) || (!height) || (!req_comps))3176return nullptr;31773178if ((req_comps != 1) && (req_comps != 3) && (req_comps != 4))3179return nullptr;31803181jpeg_decoder decoder(pStream, flags);3182if (decoder.get_error_code() != JPGD_SUCCESS)3183return nullptr;31843185const int image_width = decoder.get_width(), image_height = decoder.get_height();3186*width = image_width;3187*height = image_height;3188*actual_comps = decoder.get_num_components();31893190if (decoder.begin_decoding() != JPGD_SUCCESS)3191return nullptr;31923193const int dst_bpl = image_width * req_comps;31943195uint8* pImage_data = (uint8*)jpgd_malloc(dst_bpl * image_height);3196if (!pImage_data)3197return nullptr;31983199for (int y = 0; y < image_height; y++)3200{3201const uint8* pScan_line;3202uint scan_line_len;3203if (decoder.decode((const void**)&pScan_line, &scan_line_len) != JPGD_SUCCESS)3204{3205jpgd_free(pImage_data);3206return nullptr;3207}32083209uint8* pDst = pImage_data + y * dst_bpl;32103211if (((req_comps == 1) && (decoder.get_num_components() == 1)) || ((req_comps == 4) && (decoder.get_num_components() == 3)))3212memcpy(pDst, pScan_line, dst_bpl);3213else if (decoder.get_num_components() == 1)3214{3215if (req_comps == 3)3216{3217for (int x = 0; x < image_width; x++)3218{3219uint8 luma = pScan_line[x];3220pDst[0] = luma;3221pDst[1] = luma;3222pDst[2] = luma;3223pDst += 3;3224}3225}3226else3227{3228for (int x = 0; x < image_width; x++)3229{3230uint8 luma = pScan_line[x];3231pDst[0] = luma;3232pDst[1] = luma;3233pDst[2] = luma;3234pDst[3] = 255;3235pDst += 4;3236}3237}3238}3239else if (decoder.get_num_components() == 3)3240{3241if (req_comps == 1)3242{3243const int YR = 19595, YG = 38470, YB = 7471;3244for (int x = 0; x < image_width; x++)3245{3246int r = pScan_line[x * 4 + 0];3247int g = pScan_line[x * 4 + 1];3248int b = pScan_line[x * 4 + 2];3249*pDst++ = static_cast<uint8>((r * YR + g * YG + b * YB + 32768) >> 16);3250}3251}3252else3253{3254for (int x = 0; x < image_width; x++)3255{3256pDst[0] = pScan_line[x * 4 + 0];3257pDst[1] = pScan_line[x * 4 + 1];3258pDst[2] = pScan_line[x * 4 + 2];3259pDst += 3;3260}3261}3262}3263}32643265return pImage_data;3266}32673268unsigned 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)3269{3270jpgd::jpeg_decoder_mem_stream mem_stream(pSrc_data, src_data_size);3271return decompress_jpeg_image_from_stream(&mem_stream, width, height, actual_comps, req_comps, flags);3272}32733274unsigned char* decompress_jpeg_image_from_file(const char* pSrc_filename, int* width, int* height, int* actual_comps, int req_comps, uint32_t flags)3275{3276jpgd::jpeg_decoder_file_stream file_stream;3277if (!file_stream.open(pSrc_filename))3278return nullptr;3279return decompress_jpeg_image_from_stream(&file_stream, width, height, actual_comps, req_comps, flags);3280}32813282} // namespace jpgd328332843285