1 // jpgd.h - C++ class for JPEG decompression. 2 // Rich Geldreich <richgel99@gmail.com> 3 // Alex Evans: Linear memory allocator (taken from jpge.h). 4 // v1.04, May. 19, 2012: Code tweaks to fix VS2008 static code analysis warnings (all looked harmless) 5 // D translation by Ketmar // Invisible Vector 6 // 7 // This is free and unencumbered software released into the public domain. 8 // 9 // Anyone is free to copy, modify, publish, use, compile, sell, or 10 // distribute this software, either in source code form or as a compiled 11 // binary, for any purpose, commercial or non-commercial, and by any 12 // means. 13 // 14 // In jurisdictions that recognize copyright laws, the author or authors 15 // of this software dedicate any and all copyright interest in the 16 // software to the public domain. We make this dedication for the benefit 17 // of the public at large and to the detriment of our heirs and 18 // successors. We intend this dedication to be an overt act of 19 // relinquishment in perpetuity of all present and future rights to this 20 // software under copyright law. 21 // 22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 25 // IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 26 // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 27 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 28 // OTHER DEALINGS IN THE SOFTWARE. 29 // 30 // For more information, please refer to <http://unlicense.org/> 31 // 32 // Supports progressive and baseline sequential JPEG image files, and the most common chroma subsampling factors: Y, H1V1, H2V1, H1V2, and H2V2. 33 // 34 // Chroma upsampling quality: H2V2 is upsampled in the frequency domain, H2V1 and H1V2 are upsampled using point sampling. 35 // Chroma upsampling reference: "Fast Scheme for Image Size Change in the Compressed Domain" 36 // http://vision.ai.uiuc.edu/~dugad/research/dct/index.html 37 /** 38 * Loads a JPEG image from a memory buffer or a file. 39 * req_comps can be 1 (grayscale), 3 (RGB), or 4 (RGBA). 40 * On return, width/height will be set to the image's dimensions, and actual_comps will be set to the either 1 (grayscale) or 3 (RGB). 41 * Requesting a 8 or 32bpp image is currently a little faster than 24bpp because the jpeg_decoder class itself currently always unpacks to either 8 or 32bpp. 42 */ 43 /// JPEG image loading. 44 module gamut.codecs.jpegload; 45 46 import gamut.types; 47 import gamut.internals.binop; 48 import core.stdc.string : memcpy, memset; 49 import core.stdc.stdlib : malloc, free; 50 import inteli.emmintrin; 51 52 version(decodeJPEG): 53 54 nothrow: 55 @nogc: 56 57 // Set to 1 to enable freq. domain chroma upsampling on images using H2V2 subsampling (0=faster nearest neighbor sampling). 58 // This is slower, but results in higher quality on images with highly saturated colors. 59 version = JPGD_SUPPORT_FREQ_DOMAIN_UPSAMPLING; 60 61 /// Input stream interface. 62 /// This function is called when the internal input buffer is empty. 63 /// Parameters: 64 /// pBuf - input buffer 65 /// max_bytes_to_read - maximum bytes that can be written to pBuf 66 /// pEOF_flag - set this to true if at end of stream (no more bytes remaining) 67 /// userData - user context for being used as closure. 68 /// Returns -1 on error, otherwise return the number of bytes actually written to the buffer (which may be 0). 69 /// Notes: This delegate will be called in a loop until you set *pEOF_flag to true or the internal buffer is full. 70 alias JpegStreamReadFunc = int function(void* pBuf, int max_bytes_to_read, bool* pEOF_flag, void* userData); 71 72 73 // ////////////////////////////////////////////////////////////////////////// // 74 private: 75 76 void *jpgd_malloc (size_t nSize) 77 { 78 return malloc(nSize); 79 } 80 81 void jpgd_free (void *p) 82 { 83 free(p); 84 } 85 86 // Success/failure error codes. 87 alias jpgd_status = int; 88 enum /*jpgd_status*/ { 89 JPGD_SUCCESS = 0, JPGD_FAILED = -1, JPGD_DONE = 1, 90 JPGD_BAD_DHT_COUNTS = -256, JPGD_BAD_DHT_INDEX, JPGD_BAD_DHT_MARKER, JPGD_BAD_DQT_MARKER, JPGD_BAD_DQT_TABLE, 91 JPGD_BAD_PRECISION, JPGD_BAD_HEIGHT, JPGD_BAD_WIDTH, JPGD_TOO_MANY_COMPONENTS, 92 JPGD_BAD_SOF_LENGTH, JPGD_BAD_VARIABLE_MARKER, JPGD_BAD_DRI_LENGTH, JPGD_BAD_SOS_LENGTH, 93 JPGD_BAD_SOS_COMP_ID, JPGD_W_EXTRA_BYTES_BEFORE_MARKER, JPGD_NO_ARITHMITIC_SUPPORT, JPGD_UNEXPECTED_MARKER, 94 JPGD_NOT_JPEG, JPGD_UNSUPPORTED_MARKER, JPGD_BAD_DQT_LENGTH, JPGD_TOO_MANY_BLOCKS, 95 JPGD_UNDEFINED_QUANT_TABLE, JPGD_UNDEFINED_HUFF_TABLE, JPGD_NOT_SINGLE_SCAN, JPGD_UNSUPPORTED_COLORSPACE, 96 JPGD_UNSUPPORTED_SAMP_FACTORS, JPGD_DECODE_ERROR, JPGD_BAD_RESTART_MARKER, JPGD_ASSERTION_ERROR, 97 JPGD_BAD_SOS_SPECTRAL, JPGD_BAD_SOS_SUCCESSIVE, JPGD_STREAM_READ, JPGD_NOTENOUGHMEM, 98 } 99 100 enum { 101 JPGD_IN_BUF_SIZE = 8192, JPGD_MAX_BLOCKS_PER_MCU = 10, JPGD_MAX_HUFF_TABLES = 8, JPGD_MAX_QUANT_TABLES = 4, 102 JPGD_MAX_COMPONENTS = 4, JPGD_MAX_COMPS_IN_SCAN = 4, JPGD_MAX_BLOCKS_PER_ROW = 8192, JPGD_MAX_HEIGHT = 16384, JPGD_MAX_WIDTH = 16384, 103 } 104 105 // DCT coefficients are stored in this sequence. 106 static immutable int[64] g_ZAG = [ 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 ]; 107 108 alias JPEG_MARKER = int; 109 enum /*JPEG_MARKER*/ { 110 M_SOF0 = 0xC0, M_SOF1 = 0xC1, M_SOF2 = 0xC2, M_SOF3 = 0xC3, M_SOF5 = 0xC5, M_SOF6 = 0xC6, M_SOF7 = 0xC7, M_JPG = 0xC8, 111 M_SOF9 = 0xC9, M_SOF10 = 0xCA, M_SOF11 = 0xCB, M_SOF13 = 0xCD, M_SOF14 = 0xCE, M_SOF15 = 0xCF, M_DHT = 0xC4, M_DAC = 0xCC, 112 M_RST0 = 0xD0, M_RST1 = 0xD1, M_RST2 = 0xD2, M_RST3 = 0xD3, M_RST4 = 0xD4, M_RST5 = 0xD5, M_RST6 = 0xD6, M_RST7 = 0xD7, 113 M_SOI = 0xD8, M_EOI = 0xD9, M_SOS = 0xDA, M_DQT = 0xDB, M_DNL = 0xDC, M_DRI = 0xDD, M_DHP = 0xDE, M_EXP = 0xDF, 114 M_APP0 = 0xE0, M_APP15 = 0xEF, M_JPG0 = 0xF0, M_JPG13 = 0xFD, M_COM = 0xFE, M_TEM = 0x01, M_ERROR = 0x100, RST0 = 0xD0, 115 } 116 117 alias JPEG_SUBSAMPLING = int; 118 enum /*JPEG_SUBSAMPLING*/ { JPGD_GRAYSCALE = 0, JPGD_YH1V1, JPGD_YH2V1, JPGD_YH1V2, JPGD_YH2V2 }; 119 120 enum CONST_BITS = 13; 121 enum PASS1_BITS = 2; 122 enum SCALEDONE = cast(int)1; 123 124 enum FIX_0_298631336 = cast(int)2446; /* FIX(0.298631336) */ 125 enum FIX_0_390180644 = cast(int)3196; /* FIX(0.390180644) */ 126 enum FIX_0_541196100 = cast(int)4433; /* FIX(0.541196100) */ 127 enum FIX_0_765366865 = cast(int)6270; /* FIX(0.765366865) */ 128 enum FIX_0_899976223 = cast(int)7373; /* FIX(0.899976223) */ 129 enum FIX_1_175875602 = cast(int)9633; /* FIX(1.175875602) */ 130 enum FIX_1_501321110 = cast(int)12299; /* FIX(1.501321110) */ 131 enum FIX_1_847759065 = cast(int)15137; /* FIX(1.847759065) */ 132 enum FIX_1_961570560 = cast(int)16069; /* FIX(1.961570560) */ 133 enum FIX_2_053119869 = cast(int)16819; /* FIX(2.053119869) */ 134 enum FIX_2_562915447 = cast(int)20995; /* FIX(2.562915447) */ 135 enum FIX_3_072711026 = cast(int)25172; /* FIX(3.072711026) */ 136 137 int DESCALE() (int x, int n) 138 { 139 return ((x + (SCALEDONE << (n-1))) >> n); 140 } 141 142 int DESCALE_ZEROSHIFT() (int x, int n) 143 { 144 pragma(inline, true); return (((x) + (128 << (n)) + (SCALEDONE << ((n)-1))) >> (n)); 145 } 146 147 ubyte CLAMP() (int i) 148 { 149 if (i < 0) i = 0; 150 if (i > 255) i = 255; 151 return cast(ubyte)i; 152 } 153 154 155 // Compiler creates a fast path 1D IDCT for X non-zero columns 156 struct Row(int NONZERO_COLS) { 157 pure nothrow @trusted @nogc: 158 static void idct(int* pTemp, const(jpeg_decoder.jpgd_block_t)* pSrc) { 159 static if (NONZERO_COLS == 0) { 160 // nothing 161 } else static if (NONZERO_COLS == 1) { 162 immutable int dcval = (pSrc[0] << PASS1_BITS); 163 pTemp[0] = dcval; 164 pTemp[1] = dcval; 165 pTemp[2] = dcval; 166 pTemp[3] = dcval; 167 pTemp[4] = dcval; 168 pTemp[5] = dcval; 169 pTemp[6] = dcval; 170 pTemp[7] = dcval; 171 } else { 172 // ACCESS_COL() will be optimized at compile time to either an array access, or 0. 173 //#define ACCESS_COL(x) (((x) < NONZERO_COLS) ? (int)pSrc[x] : 0) 174 template ACCESS_COL(int x) { 175 static if (x < NONZERO_COLS) enum ACCESS_COL = "cast(int)pSrc["~x.stringof~"]"; else enum ACCESS_COL = "0"; 176 } 177 178 immutable int z2 = mixin(ACCESS_COL!2), z3 = mixin(ACCESS_COL!6); 179 180 immutable int z1 = (z2 + z3)*FIX_0_541196100; 181 immutable int tmp2 = z1 + z3*(-FIX_1_847759065); 182 immutable int tmp3 = z1 + z2*FIX_0_765366865; 183 184 immutable int tmp0 = (mixin(ACCESS_COL!0) + mixin(ACCESS_COL!4)) << CONST_BITS; 185 immutable int tmp1 = (mixin(ACCESS_COL!0) - mixin(ACCESS_COL!4)) << CONST_BITS; 186 187 immutable int tmp10 = tmp0 + tmp3, tmp13 = tmp0 - tmp3, tmp11 = tmp1 + tmp2, tmp12 = tmp1 - tmp2; 188 189 immutable int atmp0 = mixin(ACCESS_COL!7), atmp1 = mixin(ACCESS_COL!5), atmp2 = mixin(ACCESS_COL!3), atmp3 = mixin(ACCESS_COL!1); 190 191 immutable int bz1 = atmp0 + atmp3, bz2 = atmp1 + atmp2, bz3 = atmp0 + atmp2, bz4 = atmp1 + atmp3; 192 immutable int bz5 = (bz3 + bz4)*FIX_1_175875602; 193 194 immutable int az1 = bz1*(-FIX_0_899976223); 195 immutable int az2 = bz2*(-FIX_2_562915447); 196 immutable int az3 = bz3*(-FIX_1_961570560) + bz5; 197 immutable int az4 = bz4*(-FIX_0_390180644) + bz5; 198 199 immutable int btmp0 = atmp0*FIX_0_298631336 + az1 + az3; 200 immutable int btmp1 = atmp1*FIX_2_053119869 + az2 + az4; 201 immutable int btmp2 = atmp2*FIX_3_072711026 + az2 + az3; 202 immutable int btmp3 = atmp3*FIX_1_501321110 + az1 + az4; 203 204 pTemp[0] = DESCALE(tmp10 + btmp3, CONST_BITS-PASS1_BITS); 205 pTemp[7] = DESCALE(tmp10 - btmp3, CONST_BITS-PASS1_BITS); 206 pTemp[1] = DESCALE(tmp11 + btmp2, CONST_BITS-PASS1_BITS); 207 pTemp[6] = DESCALE(tmp11 - btmp2, CONST_BITS-PASS1_BITS); 208 pTemp[2] = DESCALE(tmp12 + btmp1, CONST_BITS-PASS1_BITS); 209 pTemp[5] = DESCALE(tmp12 - btmp1, CONST_BITS-PASS1_BITS); 210 pTemp[3] = DESCALE(tmp13 + btmp0, CONST_BITS-PASS1_BITS); 211 pTemp[4] = DESCALE(tmp13 - btmp0, CONST_BITS-PASS1_BITS); 212 } 213 } 214 } 215 216 217 // Compiler creates a fast path 1D IDCT for X non-zero rows 218 struct Col (int NONZERO_ROWS) { 219 pure nothrow @trusted @nogc: 220 static void idct(ubyte* pDst_ptr, const(int)* pTemp) { 221 static assert(NONZERO_ROWS > 0); 222 static if (NONZERO_ROWS == 1) { 223 int dcval = DESCALE_ZEROSHIFT(pTemp[0], PASS1_BITS+3); 224 immutable ubyte dcval_clamped = cast(ubyte)CLAMP(dcval); 225 pDst_ptr[0*8] = dcval_clamped; 226 pDst_ptr[1*8] = dcval_clamped; 227 pDst_ptr[2*8] = dcval_clamped; 228 pDst_ptr[3*8] = dcval_clamped; 229 pDst_ptr[4*8] = dcval_clamped; 230 pDst_ptr[5*8] = dcval_clamped; 231 pDst_ptr[6*8] = dcval_clamped; 232 pDst_ptr[7*8] = dcval_clamped; 233 } else { 234 // ACCESS_ROW() will be optimized at compile time to either an array access, or 0. 235 //#define ACCESS_ROW(x) (((x) < NONZERO_ROWS) ? pTemp[x * 8] : 0) 236 template ACCESS_ROW(int x) { 237 static if (x < NONZERO_ROWS) enum ACCESS_ROW = "pTemp["~(x*8).stringof~"]"; else enum ACCESS_ROW = "0"; 238 } 239 240 immutable int z2 = mixin(ACCESS_ROW!2); 241 immutable int z3 = mixin(ACCESS_ROW!6); 242 243 immutable int z1 = (z2 + z3)*FIX_0_541196100; 244 immutable int tmp2 = z1 + z3*(-FIX_1_847759065); 245 immutable int tmp3 = z1 + z2*FIX_0_765366865; 246 247 immutable int tmp0 = (mixin(ACCESS_ROW!0) + mixin(ACCESS_ROW!4)) << CONST_BITS; 248 immutable int tmp1 = (mixin(ACCESS_ROW!0) - mixin(ACCESS_ROW!4)) << CONST_BITS; 249 250 immutable int tmp10 = tmp0 + tmp3, tmp13 = tmp0 - tmp3, tmp11 = tmp1 + tmp2, tmp12 = tmp1 - tmp2; 251 252 immutable int atmp0 = mixin(ACCESS_ROW!7), atmp1 = mixin(ACCESS_ROW!5), atmp2 = mixin(ACCESS_ROW!3), atmp3 = mixin(ACCESS_ROW!1); 253 254 immutable int bz1 = atmp0 + atmp3, bz2 = atmp1 + atmp2, bz3 = atmp0 + atmp2, bz4 = atmp1 + atmp3; 255 immutable int bz5 = (bz3 + bz4)*FIX_1_175875602; 256 257 immutable int az1 = bz1*(-FIX_0_899976223); 258 immutable int az2 = bz2*(-FIX_2_562915447); 259 immutable int az3 = bz3*(-FIX_1_961570560) + bz5; 260 immutable int az4 = bz4*(-FIX_0_390180644) + bz5; 261 262 immutable int btmp0 = atmp0*FIX_0_298631336 + az1 + az3; 263 immutable int btmp1 = atmp1*FIX_2_053119869 + az2 + az4; 264 immutable int btmp2 = atmp2*FIX_3_072711026 + az2 + az3; 265 immutable int btmp3 = atmp3*FIX_1_501321110 + az1 + az4; 266 267 int i = DESCALE_ZEROSHIFT(tmp10 + btmp3, CONST_BITS+PASS1_BITS+3); 268 pDst_ptr[8*0] = cast(ubyte)CLAMP(i); 269 270 i = DESCALE_ZEROSHIFT(tmp10 - btmp3, CONST_BITS+PASS1_BITS+3); 271 pDst_ptr[8*7] = cast(ubyte)CLAMP(i); 272 273 i = DESCALE_ZEROSHIFT(tmp11 + btmp2, CONST_BITS+PASS1_BITS+3); 274 pDst_ptr[8*1] = cast(ubyte)CLAMP(i); 275 276 i = DESCALE_ZEROSHIFT(tmp11 - btmp2, CONST_BITS+PASS1_BITS+3); 277 pDst_ptr[8*6] = cast(ubyte)CLAMP(i); 278 279 i = DESCALE_ZEROSHIFT(tmp12 + btmp1, CONST_BITS+PASS1_BITS+3); 280 pDst_ptr[8*2] = cast(ubyte)CLAMP(i); 281 282 i = DESCALE_ZEROSHIFT(tmp12 - btmp1, CONST_BITS+PASS1_BITS+3); 283 pDst_ptr[8*5] = cast(ubyte)CLAMP(i); 284 285 i = DESCALE_ZEROSHIFT(tmp13 + btmp0, CONST_BITS+PASS1_BITS+3); 286 pDst_ptr[8*3] = cast(ubyte)CLAMP(i); 287 288 i = DESCALE_ZEROSHIFT(tmp13 - btmp0, CONST_BITS+PASS1_BITS+3); 289 pDst_ptr[8*4] = cast(ubyte)CLAMP(i); 290 } 291 } 292 } 293 294 295 static immutable ubyte[512] s_idct_row_table = [ 296 1,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, 297 4,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, 298 6,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, 299 6,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, 300 8,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, 301 8,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, 302 8,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, 303 8,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, 304 ]; 305 306 static immutable ubyte[64] s_idct_col_table = [ 1, 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, 7, 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, 8 ]; 307 308 void idct() (const(jpeg_decoder.jpgd_block_t)* pSrc_ptr, ubyte* pDst_ptr, int block_max_zag) { 309 assert(block_max_zag >= 1); 310 assert(block_max_zag <= 64); 311 312 if (block_max_zag <= 1) 313 { 314 int k = ((pSrc_ptr[0] + 4) >> 3) + 128; 315 k = CLAMP(k); 316 k = k | (k<<8); 317 k = k | (k<<16); 318 319 for (int i = 8; i > 0; i--) 320 { 321 *cast(int*)&pDst_ptr[0] = k; 322 *cast(int*)&pDst_ptr[4] = k; 323 pDst_ptr += 8; 324 } 325 return; 326 } 327 328 int[64] temp; 329 330 const(jpeg_decoder.jpgd_block_t)* pSrc = pSrc_ptr; 331 int* pTemp = temp.ptr; 332 333 const(ubyte)* pRow_tab = &s_idct_row_table.ptr[(block_max_zag - 1) * 8]; 334 int i; 335 for (i = 8; i > 0; i--, pRow_tab++) 336 { 337 switch (*pRow_tab) 338 { 339 case 0: Row!(0).idct(pTemp, pSrc); break; 340 case 1: Row!(1).idct(pTemp, pSrc); break; 341 case 2: Row!(2).idct(pTemp, pSrc); break; 342 case 3: Row!(3).idct(pTemp, pSrc); break; 343 case 4: Row!(4).idct(pTemp, pSrc); break; 344 case 5: Row!(5).idct(pTemp, pSrc); break; 345 case 6: Row!(6).idct(pTemp, pSrc); break; 346 case 7: Row!(7).idct(pTemp, pSrc); break; 347 case 8: Row!(8).idct(pTemp, pSrc); break; 348 default: assert(0); 349 } 350 351 pSrc += 8; 352 pTemp += 8; 353 } 354 355 pTemp = temp.ptr; 356 357 immutable int nonzero_rows = s_idct_col_table.ptr[block_max_zag - 1]; 358 for (i = 8; i > 0; i--) 359 { 360 switch (nonzero_rows) 361 { 362 case 1: Col!(1).idct(pDst_ptr, pTemp); break; 363 case 2: Col!(2).idct(pDst_ptr, pTemp); break; 364 case 3: Col!(3).idct(pDst_ptr, pTemp); break; 365 case 4: Col!(4).idct(pDst_ptr, pTemp); break; 366 case 5: Col!(5).idct(pDst_ptr, pTemp); break; 367 case 6: Col!(6).idct(pDst_ptr, pTemp); break; 368 case 7: Col!(7).idct(pDst_ptr, pTemp); break; 369 case 8: Col!(8).idct(pDst_ptr, pTemp); break; 370 default: assert(0); 371 } 372 373 pTemp++; 374 pDst_ptr++; 375 } 376 } 377 378 void idct_4x4() (const(jpeg_decoder.jpgd_block_t)* pSrc_ptr, ubyte* pDst_ptr) { 379 int[64] temp; 380 int* pTemp = temp.ptr; 381 const(jpeg_decoder.jpgd_block_t)* pSrc = pSrc_ptr; 382 383 for (int i = 4; i > 0; i--) 384 { 385 Row!(4).idct(pTemp, pSrc); 386 pSrc += 8; 387 pTemp += 8; 388 } 389 390 pTemp = temp.ptr; 391 for (int i = 8; i > 0; i--) 392 { 393 Col!(4).idct(pDst_ptr, pTemp); 394 pTemp++; 395 pDst_ptr++; 396 } 397 } 398 399 400 // ////////////////////////////////////////////////////////////////////////// // 401 struct jpeg_decoder { 402 nothrow: 403 @nogc: 404 405 private: 406 static auto JPGD_MIN(T) (T a, T b) pure nothrow @safe @nogc { pragma(inline, true); return (a < b ? a : b); } 407 static auto JPGD_MAX(T) (T a, T b) pure nothrow @safe @nogc { pragma(inline, true); return (a > b ? a : b); } 408 409 alias jpgd_quant_t = short; 410 alias jpgd_block_t = short; 411 alias pDecode_block_func = void function (ref jpeg_decoder, int, int, int); 412 413 static struct huff_tables { 414 bool ac_table; 415 uint[256] look_up; 416 uint[256] look_up2; 417 ubyte[256] code_size; 418 uint[512] tree; 419 } 420 421 static struct coeff_buf { 422 ubyte* pData; 423 int block_num_x, block_num_y; 424 int block_len_x, block_len_y; 425 int block_size; 426 } 427 428 static struct mem_block { 429 mem_block* m_pNext; 430 size_t m_used_count; 431 size_t m_size; 432 char[1] m_data; 433 } 434 435 mem_block* m_pMem_blocks; 436 int m_image_x_size; 437 int m_image_y_size; 438 JpegStreamReadFunc readfn; 439 void* userData; 440 int m_progressive_flag; 441 ubyte[JPGD_MAX_HUFF_TABLES] m_huff_ac; 442 ubyte*[JPGD_MAX_HUFF_TABLES] m_huff_num; // pointer to number of Huffman codes per bit size 443 ubyte*[JPGD_MAX_HUFF_TABLES] m_huff_val; // pointer to Huffman codes per bit size 444 jpgd_quant_t*[JPGD_MAX_QUANT_TABLES] m_quant; // pointer to quantization tables 445 int m_scan_type; // Gray, Yh1v1, Yh1v2, Yh2v1, Yh2v2 (CMYK111, CMYK4114 no longer supported) 446 int m_comps_in_frame; // # of components in frame 447 int[JPGD_MAX_COMPONENTS] m_comp_h_samp; // component's horizontal sampling factor 448 int[JPGD_MAX_COMPONENTS] m_comp_v_samp; // component's vertical sampling factor 449 int[JPGD_MAX_COMPONENTS] m_comp_quant; // component's quantization table selector 450 int[JPGD_MAX_COMPONENTS] m_comp_ident; // component's ID 451 int[JPGD_MAX_COMPONENTS] m_comp_h_blocks; 452 int[JPGD_MAX_COMPONENTS] m_comp_v_blocks; 453 int m_comps_in_scan; // # of components in scan 454 int[JPGD_MAX_COMPS_IN_SCAN] m_comp_list; // components in this scan 455 int[JPGD_MAX_COMPONENTS] m_comp_dc_tab; // component's DC Huffman coding table selector 456 int[JPGD_MAX_COMPONENTS] m_comp_ac_tab; // component's AC Huffman coding table selector 457 int m_spectral_start; // spectral selection start 458 int m_spectral_end; // spectral selection end 459 int m_successive_low; // successive approximation low 460 int m_successive_high; // successive approximation high 461 int m_max_mcu_x_size; // MCU's max. X size in pixels 462 int m_max_mcu_y_size; // MCU's max. Y size in pixels 463 int m_blocks_per_mcu; 464 int m_max_blocks_per_row; 465 int m_mcus_per_row, m_mcus_per_col; 466 int[JPGD_MAX_BLOCKS_PER_MCU] m_mcu_org; 467 int m_total_lines_left; // total # lines left in image 468 int m_mcu_lines_left; // total # lines left in this MCU 469 int m_real_dest_bytes_per_scan_line; 470 int m_dest_bytes_per_scan_line; // rounded up 471 int m_dest_bytes_per_pixel; // 4 (RGB) or 1 (Y) 472 huff_tables*[JPGD_MAX_HUFF_TABLES] m_pHuff_tabs; 473 coeff_buf*[JPGD_MAX_COMPONENTS] m_dc_coeffs; 474 coeff_buf*[JPGD_MAX_COMPONENTS] m_ac_coeffs; 475 int m_eob_run; 476 int[JPGD_MAX_COMPONENTS] m_block_y_mcu; 477 ubyte* m_pIn_buf_ofs; 478 int m_in_buf_left; 479 int m_tem_flag; 480 bool m_eof_flag; 481 ubyte[128] m_in_buf_pad_start; 482 ubyte[JPGD_IN_BUF_SIZE+128] m_in_buf; 483 ubyte[128] m_in_buf_pad_end; 484 int m_bits_left; 485 uint m_bit_buf; 486 int m_restart_interval; 487 int m_restarts_left; 488 int m_next_restart_num; 489 int m_max_mcus_per_row; 490 int m_max_blocks_per_mcu; 491 int m_expanded_blocks_per_mcu; 492 int m_expanded_blocks_per_row; 493 int m_expanded_blocks_per_component; 494 bool m_freq_domain_chroma_upsample; 495 int m_max_mcus_per_col; 496 uint[JPGD_MAX_COMPONENTS] m_last_dc_val; 497 jpgd_block_t* m_pMCU_coefficients; 498 int[JPGD_MAX_BLOCKS_PER_MCU] m_mcu_block_max_zag; 499 ubyte* m_pSample_buf; 500 int[256] m_crr; 501 int[256] m_cbb; 502 int[256] m_crg; 503 int[256] m_cbg; 504 ubyte* m_pScan_line_0; 505 ubyte* m_pScan_line_1; 506 jpgd_status m_error_code; 507 bool m_ready_flag; 508 int m_total_bytes_read; 509 510 float m_pixelsPerInchX; 511 float m_pixelsPerInchY; // -1 if not available 512 float m_pixelAspectRatio; // -1 if not available 513 514 public: 515 // Inspect `error_code` after constructing to determine if the stream is valid or not. You may look at the `width`, `height`, etc. 516 // methods after the constructor is called. You may then either destruct the object, or begin decoding the image by calling begin_decoding(), then decode() on each scanline. 517 this (JpegStreamReadFunc rfn, void* userData) 518 { 519 decode_init(rfn, userData); 520 } 521 522 ~this () { free_all_blocks(); } 523 524 @disable this (this); // no copies 525 526 // Call this method after constructing the object to begin decompression. 527 // If JPGD_SUCCESS is returned you may then call decode() on each scanline. 528 int begin_decoding () { 529 if (m_ready_flag) return JPGD_SUCCESS; 530 if (m_error_code) return JPGD_FAILED; 531 532 decode_start(); 533 m_ready_flag = true; 534 return JPGD_SUCCESS; 535 } 536 537 // Returns the next scan line. 538 // For grayscale images, pScan_line will point to a buffer containing 8-bit pixels (`bytes_per_pixel` will return 1). 539 // Otherwise, it will always point to a buffer containing 32-bit RGBA pixels (A will always be 255, and `bytes_per_pixel` will return 4). 540 // Returns JPGD_SUCCESS if a scan line has been returned. 541 // Returns JPGD_DONE if all scan lines have been returned. 542 // Returns JPGD_FAILED if an error occurred. Inspect `error_code` for a more info. 543 int decode (/*const void** */void** pScan_line, uint* pScan_line_len) { 544 if (m_error_code || !m_ready_flag) return JPGD_FAILED; 545 if (m_total_lines_left == 0) return JPGD_DONE; 546 547 if (m_mcu_lines_left == 0) { 548 if (m_progressive_flag) load_next_row(); else decode_next_row(); 549 // Find the EOI marker if that was the last row. 550 if (m_total_lines_left <= m_max_mcu_y_size) find_eoi(); 551 m_mcu_lines_left = m_max_mcu_y_size; 552 } 553 if (m_freq_domain_chroma_upsample) { 554 expanded_convert(); 555 *pScan_line = m_pScan_line_0; 556 } else { 557 switch (m_scan_type) { 558 case JPGD_YH2V2: 559 if ((m_mcu_lines_left & 1) == 0) { 560 H2V2Convert(); 561 *pScan_line = m_pScan_line_0; 562 } else { 563 *pScan_line = m_pScan_line_1; 564 } 565 break; 566 case JPGD_YH2V1: 567 H2V1Convert(); 568 *pScan_line = m_pScan_line_0; 569 break; 570 case JPGD_YH1V2: 571 if ((m_mcu_lines_left & 1) == 0) { 572 H1V2Convert(); 573 *pScan_line = m_pScan_line_0; 574 } else { 575 *pScan_line = m_pScan_line_1; 576 } 577 break; 578 case JPGD_YH1V1: 579 H1V1Convert(); 580 *pScan_line = m_pScan_line_0; 581 break; 582 case JPGD_GRAYSCALE: 583 gray_convert(); 584 *pScan_line = m_pScan_line_0; 585 break; 586 default: 587 } 588 } 589 *pScan_line_len = m_real_dest_bytes_per_scan_line; 590 --m_mcu_lines_left; 591 --m_total_lines_left; 592 return JPGD_SUCCESS; 593 } 594 595 @property const pure nothrow @safe @nogc { 596 jpgd_status error_code () { return m_error_code; } 597 598 int width () { return m_image_x_size; } 599 int height () { return m_image_y_size; } 600 601 int num_components () { return m_comps_in_frame; } 602 603 int bytes_per_pixel () { return m_dest_bytes_per_pixel; } 604 int bytes_per_scan_line () { return m_image_x_size * bytes_per_pixel(); } 605 606 // Returns the total number of bytes actually consumed by the decoder (which should equal the actual size of the JPEG file). 607 int total_bytes_read () { return m_total_bytes_read; } 608 } 609 610 private: 611 // Retrieve one character from the input stream. 612 uint get_char () { 613 // Any bytes remaining in buffer? 614 if (!m_in_buf_left) { 615 // Try to get more bytes. 616 prep_in_buffer(); 617 // Still nothing to get? 618 if (!m_in_buf_left) { 619 // Pad the end of the stream with 0xFF 0xD9 (EOI marker) 620 int t = m_tem_flag; 621 m_tem_flag ^= 1; 622 return (t ? 0xD9 : 0xFF); 623 } 624 } 625 uint c = *m_pIn_buf_ofs++; 626 --m_in_buf_left; 627 return c; 628 } 629 630 // Same as previous method, except can indicate if the character is a pad character or not. 631 uint get_char (bool* pPadding_flag) { 632 if (!m_in_buf_left) { 633 prep_in_buffer(); 634 if (!m_in_buf_left) { 635 *pPadding_flag = true; 636 int t = m_tem_flag; 637 m_tem_flag ^= 1; 638 return (t ? 0xD9 : 0xFF); 639 } 640 } 641 *pPadding_flag = false; 642 uint c = *m_pIn_buf_ofs++; 643 --m_in_buf_left; 644 return c; 645 } 646 647 // Inserts a previously retrieved character back into the input buffer. 648 void stuff_char (ubyte q) { 649 *(--m_pIn_buf_ofs) = q; 650 m_in_buf_left++; 651 } 652 653 // Retrieves one character from the input stream, but does not read past markers. Will continue to return 0xFF when a marker is encountered. 654 ubyte get_octet () { 655 bool padding_flag; 656 int c = get_char(&padding_flag); 657 if (c == 0xFF) { 658 if (padding_flag) return 0xFF; 659 c = get_char(&padding_flag); 660 if (padding_flag) { stuff_char(0xFF); return 0xFF; } 661 if (c == 0x00) return 0xFF; 662 stuff_char(cast(ubyte)(c)); 663 stuff_char(0xFF); 664 return 0xFF; 665 } 666 return cast(ubyte)(c); 667 } 668 669 // Retrieves a variable number of bits from the input stream. Does not recognize markers. 670 uint get_bits (int num_bits) { 671 if (!num_bits) return 0; 672 uint i = m_bit_buf >> (32 - num_bits); 673 if ((m_bits_left -= num_bits) <= 0) { 674 m_bit_buf <<= (num_bits += m_bits_left); 675 uint c1 = get_char(); 676 uint c2 = get_char(); 677 m_bit_buf = (m_bit_buf & 0xFFFF0000) | (c1 << 8) | c2; 678 m_bit_buf <<= -m_bits_left; 679 m_bits_left += 16; 680 assert(m_bits_left >= 0); 681 } else { 682 m_bit_buf <<= num_bits; 683 } 684 return i; 685 } 686 687 // 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. 688 uint get_bits_no_markers (int num_bits) { 689 if (!num_bits) return 0; 690 uint i = m_bit_buf >> (32 - num_bits); 691 if ((m_bits_left -= num_bits) <= 0) { 692 m_bit_buf <<= (num_bits += m_bits_left); 693 if (m_in_buf_left < 2 || m_pIn_buf_ofs[0] == 0xFF || m_pIn_buf_ofs[1] == 0xFF) { 694 uint c1 = get_octet(); 695 uint c2 = get_octet(); 696 m_bit_buf |= (c1 << 8) | c2; 697 } else { 698 m_bit_buf |= (cast(uint)m_pIn_buf_ofs[0] << 8) | m_pIn_buf_ofs[1]; 699 m_in_buf_left -= 2; 700 m_pIn_buf_ofs += 2; 701 } 702 m_bit_buf <<= -m_bits_left; 703 m_bits_left += 16; 704 assert(m_bits_left >= 0); 705 } else { 706 m_bit_buf <<= num_bits; 707 } 708 return i; 709 } 710 711 // Decodes a Huffman encoded symbol. 712 int huff_decode (huff_tables *pH) { 713 int symbol; 714 // Check first 8-bits: do we have a complete symbol? 715 if ((symbol = pH.look_up.ptr[m_bit_buf >> 24]) < 0) { 716 // Decode more bits, use a tree traversal to find symbol. 717 int ofs = 23; 718 do { 719 symbol = pH.tree.ptr[-cast(int)(symbol + ((m_bit_buf >> ofs) & 1))]; 720 --ofs; 721 } while (symbol < 0); 722 get_bits_no_markers(8 + (23 - ofs)); 723 } else { 724 get_bits_no_markers(pH.code_size.ptr[symbol]); 725 } 726 return symbol; 727 } 728 729 // Decodes a Huffman encoded symbol. 730 int huff_decode (huff_tables *pH, ref int extra_bits) { 731 int symbol; 732 // Check first 8-bits: do we have a complete symbol? 733 if ((symbol = pH.look_up2.ptr[m_bit_buf >> 24]) < 0) { 734 // Use a tree traversal to find symbol. 735 int ofs = 23; 736 do { 737 symbol = pH.tree.ptr[-cast(int)(symbol + ((m_bit_buf >> ofs) & 1))]; 738 --ofs; 739 } while (symbol < 0); 740 get_bits_no_markers(8 + (23 - ofs)); 741 extra_bits = get_bits_no_markers(symbol & 0xF); 742 } else { 743 assert(((symbol >> 8) & 31) == pH.code_size.ptr[symbol & 255] + ((symbol & 0x8000) ? (symbol & 15) : 0)); 744 if (symbol & 0x8000) { 745 get_bits_no_markers((symbol >> 8) & 31); 746 extra_bits = symbol >> 16; 747 } else { 748 int code_size = (symbol >> 8) & 31; 749 int num_extra_bits = symbol & 0xF; 750 int bits = code_size + num_extra_bits; 751 if (bits <= (m_bits_left + 16)) { 752 extra_bits = get_bits_no_markers(bits) & ((1 << num_extra_bits) - 1); 753 } else { 754 get_bits_no_markers(code_size); 755 extra_bits = get_bits_no_markers(num_extra_bits); 756 } 757 } 758 symbol &= 0xFF; 759 } 760 return symbol; 761 } 762 763 // Tables and macro used to fully decode the DPCM differences. 764 static immutable int[16] s_extend_test = [ 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 ]; 765 static immutable int[16] s_extend_offset = [ 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1, ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1, ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1, ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1 ]; 766 767 static int JPGD_HUFF_EXTEND (int x, int s) nothrow @trusted @nogc 768 { 769 return (((x) < s_extend_test.ptr[s]) ? ((x) + s_extend_offset.ptr[s]) : (x)); 770 } 771 772 // Clamps a value between 0-255. 773 alias clamp = CLAMP; 774 775 static struct DCT_Upsample { 776 static: 777 static struct Matrix44 { 778 pure nothrow @trusted @nogc: 779 alias Element_Type = int; 780 enum { NUM_ROWS = 4, NUM_COLS = 4 } 781 782 Element_Type[NUM_COLS][NUM_ROWS] v; 783 784 this() (in Matrix44 m) { 785 foreach (immutable r; 0..NUM_ROWS) v[r][] = m.v[r][]; 786 } 787 788 ref inout(Element_Type) at (int r, int c) inout { pragma(inline, true); return v.ptr[r].ptr[c]; } 789 790 ref Matrix44 opOpAssign(string op:"+") (in Matrix44 a) { 791 foreach (int r; 0..NUM_ROWS) { 792 at(r, 0) += a.at(r, 0); 793 at(r, 1) += a.at(r, 1); 794 at(r, 2) += a.at(r, 2); 795 at(r, 3) += a.at(r, 3); 796 } 797 return this; 798 } 799 800 ref Matrix44 opOpAssign(string op:"-") (in Matrix44 a) { 801 foreach (int r; 0..NUM_ROWS) { 802 at(r, 0) -= a.at(r, 0); 803 at(r, 1) -= a.at(r, 1); 804 at(r, 2) -= a.at(r, 2); 805 at(r, 3) -= a.at(r, 3); 806 } 807 return this; 808 } 809 810 Matrix44 opBinary(string op:"+") (in Matrix44 b) const { 811 alias a = this; 812 Matrix44 ret; 813 foreach (int r; 0..NUM_ROWS) { 814 ret.at(r, 0) = a.at(r, 0) + b.at(r, 0); 815 ret.at(r, 1) = a.at(r, 1) + b.at(r, 1); 816 ret.at(r, 2) = a.at(r, 2) + b.at(r, 2); 817 ret.at(r, 3) = a.at(r, 3) + b.at(r, 3); 818 } 819 return ret; 820 } 821 822 Matrix44 opBinary(string op:"-") (in Matrix44 b) const { 823 alias a = this; 824 Matrix44 ret; 825 foreach (int r; 0..NUM_ROWS) { 826 ret.at(r, 0) = a.at(r, 0) - b.at(r, 0); 827 ret.at(r, 1) = a.at(r, 1) - b.at(r, 1); 828 ret.at(r, 2) = a.at(r, 2) - b.at(r, 2); 829 ret.at(r, 3) = a.at(r, 3) - b.at(r, 3); 830 } 831 return ret; 832 } 833 834 static void add_and_store() (jpgd_block_t* pDst, in Matrix44 a, in Matrix44 b) { 835 foreach (int r; 0..4) { 836 pDst[0*8 + r] = cast(jpgd_block_t)(a.at(r, 0) + b.at(r, 0)); 837 pDst[1*8 + r] = cast(jpgd_block_t)(a.at(r, 1) + b.at(r, 1)); 838 pDst[2*8 + r] = cast(jpgd_block_t)(a.at(r, 2) + b.at(r, 2)); 839 pDst[3*8 + r] = cast(jpgd_block_t)(a.at(r, 3) + b.at(r, 3)); 840 } 841 } 842 843 static void sub_and_store() (jpgd_block_t* pDst, in Matrix44 a, in Matrix44 b) { 844 foreach (int r; 0..4) { 845 pDst[0*8 + r] = cast(jpgd_block_t)(a.at(r, 0) - b.at(r, 0)); 846 pDst[1*8 + r] = cast(jpgd_block_t)(a.at(r, 1) - b.at(r, 1)); 847 pDst[2*8 + r] = cast(jpgd_block_t)(a.at(r, 2) - b.at(r, 2)); 848 pDst[3*8 + r] = cast(jpgd_block_t)(a.at(r, 3) - b.at(r, 3)); 849 } 850 } 851 } 852 853 enum FRACT_BITS = 10; 854 enum SCALE = 1 << FRACT_BITS; 855 856 alias Temp_Type = int; 857 858 static int D(T) (T i) { pragma(inline, true); return (((i) + (SCALE >> 1)) >> FRACT_BITS); } 859 enum F(float i) = (cast(int)((i) * SCALE + 0.5f)); 860 861 // NUM_ROWS/NUM_COLS = # of non-zero rows/cols in input matrix 862 static struct P_Q(int NUM_ROWS, int NUM_COLS) { 863 static void calc (ref Matrix44 P, ref Matrix44 Q, const(jpgd_block_t)* pSrc) { 864 //auto AT (int c, int r) nothrow @trusted @nogc { return (c >= NUM_COLS || r >= NUM_ROWS ? 0 : pSrc[c+r*8]); } 865 template AT(int c, int r) { 866 static if (c >= NUM_COLS || r >= NUM_ROWS) enum AT = "0"; else enum AT = "pSrc["~c.stringof~"+"~r.stringof~"*8]"; 867 } 868 // 4x8 = 4x8 times 8x8, matrix 0 is constant 869 immutable Temp_Type X000 = mixin(AT!(0, 0)); 870 immutable Temp_Type X001 = mixin(AT!(0, 1)); 871 immutable Temp_Type X002 = mixin(AT!(0, 2)); 872 immutable Temp_Type X003 = mixin(AT!(0, 3)); 873 immutable Temp_Type X004 = mixin(AT!(0, 4)); 874 immutable Temp_Type X005 = mixin(AT!(0, 5)); 875 immutable Temp_Type X006 = mixin(AT!(0, 6)); 876 immutable Temp_Type X007 = mixin(AT!(0, 7)); 877 immutable Temp_Type X010 = D(F!(0.415735f) * mixin(AT!(1, 0)) + F!(0.791065f) * mixin(AT!(3, 0)) + F!(-0.352443f) * mixin(AT!(5, 0)) + F!(0.277785f) * mixin(AT!(7, 0))); 878 immutable Temp_Type X011 = D(F!(0.415735f) * mixin(AT!(1, 1)) + F!(0.791065f) * mixin(AT!(3, 1)) + F!(-0.352443f) * mixin(AT!(5, 1)) + F!(0.277785f) * mixin(AT!(7, 1))); 879 immutable Temp_Type X012 = D(F!(0.415735f) * mixin(AT!(1, 2)) + F!(0.791065f) * mixin(AT!(3, 2)) + F!(-0.352443f) * mixin(AT!(5, 2)) + F!(0.277785f) * mixin(AT!(7, 2))); 880 immutable Temp_Type X013 = D(F!(0.415735f) * mixin(AT!(1, 3)) + F!(0.791065f) * mixin(AT!(3, 3)) + F!(-0.352443f) * mixin(AT!(5, 3)) + F!(0.277785f) * mixin(AT!(7, 3))); 881 immutable Temp_Type X014 = D(F!(0.415735f) * mixin(AT!(1, 4)) + F!(0.791065f) * mixin(AT!(3, 4)) + F!(-0.352443f) * mixin(AT!(5, 4)) + F!(0.277785f) * mixin(AT!(7, 4))); 882 immutable Temp_Type X015 = D(F!(0.415735f) * mixin(AT!(1, 5)) + F!(0.791065f) * mixin(AT!(3, 5)) + F!(-0.352443f) * mixin(AT!(5, 5)) + F!(0.277785f) * mixin(AT!(7, 5))); 883 immutable Temp_Type X016 = D(F!(0.415735f) * mixin(AT!(1, 6)) + F!(0.791065f) * mixin(AT!(3, 6)) + F!(-0.352443f) * mixin(AT!(5, 6)) + F!(0.277785f) * mixin(AT!(7, 6))); 884 immutable Temp_Type X017 = D(F!(0.415735f) * mixin(AT!(1, 7)) + F!(0.791065f) * mixin(AT!(3, 7)) + F!(-0.352443f) * mixin(AT!(5, 7)) + F!(0.277785f) * mixin(AT!(7, 7))); 885 immutable Temp_Type X020 = mixin(AT!(4, 0)); 886 immutable Temp_Type X021 = mixin(AT!(4, 1)); 887 immutable Temp_Type X022 = mixin(AT!(4, 2)); 888 immutable Temp_Type X023 = mixin(AT!(4, 3)); 889 immutable Temp_Type X024 = mixin(AT!(4, 4)); 890 immutable Temp_Type X025 = mixin(AT!(4, 5)); 891 immutable Temp_Type X026 = mixin(AT!(4, 6)); 892 immutable Temp_Type X027 = mixin(AT!(4, 7)); 893 immutable Temp_Type X030 = D(F!(0.022887f) * mixin(AT!(1, 0)) + F!(-0.097545f) * mixin(AT!(3, 0)) + F!(0.490393f) * mixin(AT!(5, 0)) + F!(0.865723f) * mixin(AT!(7, 0))); 894 immutable Temp_Type X031 = D(F!(0.022887f) * mixin(AT!(1, 1)) + F!(-0.097545f) * mixin(AT!(3, 1)) + F!(0.490393f) * mixin(AT!(5, 1)) + F!(0.865723f) * mixin(AT!(7, 1))); 895 immutable Temp_Type X032 = D(F!(0.022887f) * mixin(AT!(1, 2)) + F!(-0.097545f) * mixin(AT!(3, 2)) + F!(0.490393f) * mixin(AT!(5, 2)) + F!(0.865723f) * mixin(AT!(7, 2))); 896 immutable Temp_Type X033 = D(F!(0.022887f) * mixin(AT!(1, 3)) + F!(-0.097545f) * mixin(AT!(3, 3)) + F!(0.490393f) * mixin(AT!(5, 3)) + F!(0.865723f) * mixin(AT!(7, 3))); 897 immutable Temp_Type X034 = D(F!(0.022887f) * mixin(AT!(1, 4)) + F!(-0.097545f) * mixin(AT!(3, 4)) + F!(0.490393f) * mixin(AT!(5, 4)) + F!(0.865723f) * mixin(AT!(7, 4))); 898 immutable Temp_Type X035 = D(F!(0.022887f) * mixin(AT!(1, 5)) + F!(-0.097545f) * mixin(AT!(3, 5)) + F!(0.490393f) * mixin(AT!(5, 5)) + F!(0.865723f) * mixin(AT!(7, 5))); 899 immutable Temp_Type X036 = D(F!(0.022887f) * mixin(AT!(1, 6)) + F!(-0.097545f) * mixin(AT!(3, 6)) + F!(0.490393f) * mixin(AT!(5, 6)) + F!(0.865723f) * mixin(AT!(7, 6))); 900 immutable Temp_Type X037 = D(F!(0.022887f) * mixin(AT!(1, 7)) + F!(-0.097545f) * mixin(AT!(3, 7)) + F!(0.490393f) * mixin(AT!(5, 7)) + F!(0.865723f) * mixin(AT!(7, 7))); 901 902 // 4x4 = 4x8 times 8x4, matrix 1 is constant 903 P.at(0, 0) = X000; 904 P.at(0, 1) = D(X001 * F!(0.415735f) + X003 * F!(0.791065f) + X005 * F!(-0.352443f) + X007 * F!(0.277785f)); 905 P.at(0, 2) = X004; 906 P.at(0, 3) = D(X001 * F!(0.022887f) + X003 * F!(-0.097545f) + X005 * F!(0.490393f) + X007 * F!(0.865723f)); 907 P.at(1, 0) = X010; 908 P.at(1, 1) = D(X011 * F!(0.415735f) + X013 * F!(0.791065f) + X015 * F!(-0.352443f) + X017 * F!(0.277785f)); 909 P.at(1, 2) = X014; 910 P.at(1, 3) = D(X011 * F!(0.022887f) + X013 * F!(-0.097545f) + X015 * F!(0.490393f) + X017 * F!(0.865723f)); 911 P.at(2, 0) = X020; 912 P.at(2, 1) = D(X021 * F!(0.415735f) + X023 * F!(0.791065f) + X025 * F!(-0.352443f) + X027 * F!(0.277785f)); 913 P.at(2, 2) = X024; 914 P.at(2, 3) = D(X021 * F!(0.022887f) + X023 * F!(-0.097545f) + X025 * F!(0.490393f) + X027 * F!(0.865723f)); 915 P.at(3, 0) = X030; 916 P.at(3, 1) = D(X031 * F!(0.415735f) + X033 * F!(0.791065f) + X035 * F!(-0.352443f) + X037 * F!(0.277785f)); 917 P.at(3, 2) = X034; 918 P.at(3, 3) = D(X031 * F!(0.022887f) + X033 * F!(-0.097545f) + X035 * F!(0.490393f) + X037 * F!(0.865723f)); 919 // 40 muls 24 adds 920 921 // 4x4 = 4x8 times 8x4, matrix 1 is constant 922 Q.at(0, 0) = D(X001 * F!(0.906127f) + X003 * F!(-0.318190f) + X005 * F!(0.212608f) + X007 * F!(-0.180240f)); 923 Q.at(0, 1) = X002; 924 Q.at(0, 2) = D(X001 * F!(-0.074658f) + X003 * F!(0.513280f) + X005 * F!(0.768178f) + X007 * F!(-0.375330f)); 925 Q.at(0, 3) = X006; 926 Q.at(1, 0) = D(X011 * F!(0.906127f) + X013 * F!(-0.318190f) + X015 * F!(0.212608f) + X017 * F!(-0.180240f)); 927 Q.at(1, 1) = X012; 928 Q.at(1, 2) = D(X011 * F!(-0.074658f) + X013 * F!(0.513280f) + X015 * F!(0.768178f) + X017 * F!(-0.375330f)); 929 Q.at(1, 3) = X016; 930 Q.at(2, 0) = D(X021 * F!(0.906127f) + X023 * F!(-0.318190f) + X025 * F!(0.212608f) + X027 * F!(-0.180240f)); 931 Q.at(2, 1) = X022; 932 Q.at(2, 2) = D(X021 * F!(-0.074658f) + X023 * F!(0.513280f) + X025 * F!(0.768178f) + X027 * F!(-0.375330f)); 933 Q.at(2, 3) = X026; 934 Q.at(3, 0) = D(X031 * F!(0.906127f) + X033 * F!(-0.318190f) + X035 * F!(0.212608f) + X037 * F!(-0.180240f)); 935 Q.at(3, 1) = X032; 936 Q.at(3, 2) = D(X031 * F!(-0.074658f) + X033 * F!(0.513280f) + X035 * F!(0.768178f) + X037 * F!(-0.375330f)); 937 Q.at(3, 3) = X036; 938 // 40 muls 24 adds 939 } 940 } 941 942 static struct R_S(int NUM_ROWS, int NUM_COLS) { 943 static void calc(ref Matrix44 R, ref Matrix44 S, const(jpgd_block_t)* pSrc) { 944 //auto AT (int c, int r) nothrow @trusted @nogc { return (c >= NUM_COLS || r >= NUM_ROWS ? 0 : pSrc[c+r*8]); } 945 template AT(int c, int r) { 946 static if (c >= NUM_COLS || r >= NUM_ROWS) enum AT = "0"; else enum AT = "pSrc["~c.stringof~"+"~r.stringof~"*8]"; 947 } 948 // 4x8 = 4x8 times 8x8, matrix 0 is constant 949 immutable Temp_Type X100 = D(F!(0.906127f) * mixin(AT!(1, 0)) + F!(-0.318190f) * mixin(AT!(3, 0)) + F!(0.212608f) * mixin(AT!(5, 0)) + F!(-0.180240f) * mixin(AT!(7, 0))); 950 immutable Temp_Type X101 = D(F!(0.906127f) * mixin(AT!(1, 1)) + F!(-0.318190f) * mixin(AT!(3, 1)) + F!(0.212608f) * mixin(AT!(5, 1)) + F!(-0.180240f) * mixin(AT!(7, 1))); 951 immutable Temp_Type X102 = D(F!(0.906127f) * mixin(AT!(1, 2)) + F!(-0.318190f) * mixin(AT!(3, 2)) + F!(0.212608f) * mixin(AT!(5, 2)) + F!(-0.180240f) * mixin(AT!(7, 2))); 952 immutable Temp_Type X103 = D(F!(0.906127f) * mixin(AT!(1, 3)) + F!(-0.318190f) * mixin(AT!(3, 3)) + F!(0.212608f) * mixin(AT!(5, 3)) + F!(-0.180240f) * mixin(AT!(7, 3))); 953 immutable Temp_Type X104 = D(F!(0.906127f) * mixin(AT!(1, 4)) + F!(-0.318190f) * mixin(AT!(3, 4)) + F!(0.212608f) * mixin(AT!(5, 4)) + F!(-0.180240f) * mixin(AT!(7, 4))); 954 immutable Temp_Type X105 = D(F!(0.906127f) * mixin(AT!(1, 5)) + F!(-0.318190f) * mixin(AT!(3, 5)) + F!(0.212608f) * mixin(AT!(5, 5)) + F!(-0.180240f) * mixin(AT!(7, 5))); 955 immutable Temp_Type X106 = D(F!(0.906127f) * mixin(AT!(1, 6)) + F!(-0.318190f) * mixin(AT!(3, 6)) + F!(0.212608f) * mixin(AT!(5, 6)) + F!(-0.180240f) * mixin(AT!(7, 6))); 956 immutable Temp_Type X107 = D(F!(0.906127f) * mixin(AT!(1, 7)) + F!(-0.318190f) * mixin(AT!(3, 7)) + F!(0.212608f) * mixin(AT!(5, 7)) + F!(-0.180240f) * mixin(AT!(7, 7))); 957 immutable Temp_Type X110 = mixin(AT!(2, 0)); 958 immutable Temp_Type X111 = mixin(AT!(2, 1)); 959 immutable Temp_Type X112 = mixin(AT!(2, 2)); 960 immutable Temp_Type X113 = mixin(AT!(2, 3)); 961 immutable Temp_Type X114 = mixin(AT!(2, 4)); 962 immutable Temp_Type X115 = mixin(AT!(2, 5)); 963 immutable Temp_Type X116 = mixin(AT!(2, 6)); 964 immutable Temp_Type X117 = mixin(AT!(2, 7)); 965 immutable Temp_Type X120 = D(F!(-0.074658f) * mixin(AT!(1, 0)) + F!(0.513280f) * mixin(AT!(3, 0)) + F!(0.768178f) * mixin(AT!(5, 0)) + F!(-0.375330f) * mixin(AT!(7, 0))); 966 immutable Temp_Type X121 = D(F!(-0.074658f) * mixin(AT!(1, 1)) + F!(0.513280f) * mixin(AT!(3, 1)) + F!(0.768178f) * mixin(AT!(5, 1)) + F!(-0.375330f) * mixin(AT!(7, 1))); 967 immutable Temp_Type X122 = D(F!(-0.074658f) * mixin(AT!(1, 2)) + F!(0.513280f) * mixin(AT!(3, 2)) + F!(0.768178f) * mixin(AT!(5, 2)) + F!(-0.375330f) * mixin(AT!(7, 2))); 968 immutable Temp_Type X123 = D(F!(-0.074658f) * mixin(AT!(1, 3)) + F!(0.513280f) * mixin(AT!(3, 3)) + F!(0.768178f) * mixin(AT!(5, 3)) + F!(-0.375330f) * mixin(AT!(7, 3))); 969 immutable Temp_Type X124 = D(F!(-0.074658f) * mixin(AT!(1, 4)) + F!(0.513280f) * mixin(AT!(3, 4)) + F!(0.768178f) * mixin(AT!(5, 4)) + F!(-0.375330f) * mixin(AT!(7, 4))); 970 immutable Temp_Type X125 = D(F!(-0.074658f) * mixin(AT!(1, 5)) + F!(0.513280f) * mixin(AT!(3, 5)) + F!(0.768178f) * mixin(AT!(5, 5)) + F!(-0.375330f) * mixin(AT!(7, 5))); 971 immutable Temp_Type X126 = D(F!(-0.074658f) * mixin(AT!(1, 6)) + F!(0.513280f) * mixin(AT!(3, 6)) + F!(0.768178f) * mixin(AT!(5, 6)) + F!(-0.375330f) * mixin(AT!(7, 6))); 972 immutable Temp_Type X127 = D(F!(-0.074658f) * mixin(AT!(1, 7)) + F!(0.513280f) * mixin(AT!(3, 7)) + F!(0.768178f) * mixin(AT!(5, 7)) + F!(-0.375330f) * mixin(AT!(7, 7))); 973 immutable Temp_Type X130 = mixin(AT!(6, 0)); 974 immutable Temp_Type X131 = mixin(AT!(6, 1)); 975 immutable Temp_Type X132 = mixin(AT!(6, 2)); 976 immutable Temp_Type X133 = mixin(AT!(6, 3)); 977 immutable Temp_Type X134 = mixin(AT!(6, 4)); 978 immutable Temp_Type X135 = mixin(AT!(6, 5)); 979 immutable Temp_Type X136 = mixin(AT!(6, 6)); 980 immutable Temp_Type X137 = mixin(AT!(6, 7)); 981 // 80 muls 48 adds 982 983 // 4x4 = 4x8 times 8x4, matrix 1 is constant 984 R.at(0, 0) = X100; 985 R.at(0, 1) = D(X101 * F!(0.415735f) + X103 * F!(0.791065f) + X105 * F!(-0.352443f) + X107 * F!(0.277785f)); 986 R.at(0, 2) = X104; 987 R.at(0, 3) = D(X101 * F!(0.022887f) + X103 * F!(-0.097545f) + X105 * F!(0.490393f) + X107 * F!(0.865723f)); 988 R.at(1, 0) = X110; 989 R.at(1, 1) = D(X111 * F!(0.415735f) + X113 * F!(0.791065f) + X115 * F!(-0.352443f) + X117 * F!(0.277785f)); 990 R.at(1, 2) = X114; 991 R.at(1, 3) = D(X111 * F!(0.022887f) + X113 * F!(-0.097545f) + X115 * F!(0.490393f) + X117 * F!(0.865723f)); 992 R.at(2, 0) = X120; 993 R.at(2, 1) = D(X121 * F!(0.415735f) + X123 * F!(0.791065f) + X125 * F!(-0.352443f) + X127 * F!(0.277785f)); 994 R.at(2, 2) = X124; 995 R.at(2, 3) = D(X121 * F!(0.022887f) + X123 * F!(-0.097545f) + X125 * F!(0.490393f) + X127 * F!(0.865723f)); 996 R.at(3, 0) = X130; 997 R.at(3, 1) = D(X131 * F!(0.415735f) + X133 * F!(0.791065f) + X135 * F!(-0.352443f) + X137 * F!(0.277785f)); 998 R.at(3, 2) = X134; 999 R.at(3, 3) = D(X131 * F!(0.022887f) + X133 * F!(-0.097545f) + X135 * F!(0.490393f) + X137 * F!(0.865723f)); 1000 // 40 muls 24 adds 1001 // 4x4 = 4x8 times 8x4, matrix 1 is constant 1002 S.at(0, 0) = D(X101 * F!(0.906127f) + X103 * F!(-0.318190f) + X105 * F!(0.212608f) + X107 * F!(-0.180240f)); 1003 S.at(0, 1) = X102; 1004 S.at(0, 2) = D(X101 * F!(-0.074658f) + X103 * F!(0.513280f) + X105 * F!(0.768178f) + X107 * F!(-0.375330f)); 1005 S.at(0, 3) = X106; 1006 S.at(1, 0) = D(X111 * F!(0.906127f) + X113 * F!(-0.318190f) + X115 * F!(0.212608f) + X117 * F!(-0.180240f)); 1007 S.at(1, 1) = X112; 1008 S.at(1, 2) = D(X111 * F!(-0.074658f) + X113 * F!(0.513280f) + X115 * F!(0.768178f) + X117 * F!(-0.375330f)); 1009 S.at(1, 3) = X116; 1010 S.at(2, 0) = D(X121 * F!(0.906127f) + X123 * F!(-0.318190f) + X125 * F!(0.212608f) + X127 * F!(-0.180240f)); 1011 S.at(2, 1) = X122; 1012 S.at(2, 2) = D(X121 * F!(-0.074658f) + X123 * F!(0.513280f) + X125 * F!(0.768178f) + X127 * F!(-0.375330f)); 1013 S.at(2, 3) = X126; 1014 S.at(3, 0) = D(X131 * F!(0.906127f) + X133 * F!(-0.318190f) + X135 * F!(0.212608f) + X137 * F!(-0.180240f)); 1015 S.at(3, 1) = X132; 1016 S.at(3, 2) = D(X131 * F!(-0.074658f) + X133 * F!(0.513280f) + X135 * F!(0.768178f) + X137 * F!(-0.375330f)); 1017 S.at(3, 3) = X136; 1018 // 40 muls 24 adds 1019 } 1020 } 1021 } // end namespace DCT_Upsample 1022 1023 // Unconditionally frees all allocated m_blocks. 1024 void free_all_blocks () { 1025 //m_pStream = null; 1026 readfn = null; 1027 for (mem_block *b = m_pMem_blocks; b; ) { 1028 mem_block* n = b.m_pNext; 1029 jpgd_free(b); 1030 b = n; 1031 } 1032 m_pMem_blocks = null; 1033 } 1034 1035 // This method handles all errors. It will never return. 1036 // It could easily be changed to use C++ exceptions. 1037 /*JPGD_NORETURN*/ void stop_decoding (jpgd_status status) { 1038 m_error_code = status; 1039 free_all_blocks(); 1040 //longjmp(m_jmp_state, status); 1041 assert(false, "jpeg decoding error"); 1042 } 1043 1044 void* alloc (size_t nSize, bool zero=false) { 1045 nSize = (JPGD_MAX(nSize, 1) + 3) & ~3; 1046 char *rv = null; 1047 for (mem_block *b = m_pMem_blocks; b; b = b.m_pNext) 1048 { 1049 if ((b.m_used_count + nSize) <= b.m_size) 1050 { 1051 rv = b.m_data.ptr + b.m_used_count; 1052 b.m_used_count += nSize; 1053 break; 1054 } 1055 } 1056 if (!rv) 1057 { 1058 int capacity = cast(int) JPGD_MAX(32768 - 256, (nSize + 2047) & ~2047); 1059 mem_block *b = cast(mem_block*)jpgd_malloc(mem_block.sizeof + capacity); 1060 if (!b) { stop_decoding(JPGD_NOTENOUGHMEM); } 1061 b.m_pNext = m_pMem_blocks; m_pMem_blocks = b; 1062 b.m_used_count = nSize; 1063 b.m_size = capacity; 1064 rv = b.m_data.ptr; 1065 } 1066 if (zero) memset(rv, 0, nSize); 1067 return rv; 1068 } 1069 1070 void word_clear (void *p, ushort c, uint n) { 1071 ubyte *pD = cast(ubyte*)p; 1072 immutable ubyte l = c & 0xFF, h = (c >> 8) & 0xFF; 1073 while (n) 1074 { 1075 pD[0] = l; pD[1] = h; pD += 2; 1076 n--; 1077 } 1078 } 1079 1080 // Refill the input buffer. 1081 // This method will sit in a loop until (A) the buffer is full or (B) 1082 // the stream's read() method reports and end of file condition. 1083 void prep_in_buffer () { 1084 m_in_buf_left = 0; 1085 m_pIn_buf_ofs = m_in_buf.ptr; 1086 1087 if (m_eof_flag) 1088 return; 1089 1090 do 1091 { 1092 int bytes_read = readfn(m_in_buf.ptr + m_in_buf_left, JPGD_IN_BUF_SIZE - m_in_buf_left, &m_eof_flag, userData); 1093 if (bytes_read == -1) 1094 stop_decoding(JPGD_STREAM_READ); 1095 1096 m_in_buf_left += bytes_read; 1097 } while ((m_in_buf_left < JPGD_IN_BUF_SIZE) && (!m_eof_flag)); 1098 1099 m_total_bytes_read += m_in_buf_left; 1100 1101 // Pad the end of the block with M_EOI (prevents the decompressor from going off the rails if the stream is invalid). 1102 // (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.) 1103 word_clear(m_pIn_buf_ofs + m_in_buf_left, 0xD9FF, 64); 1104 } 1105 1106 // Read a Huffman code table. 1107 void read_dht_marker () { 1108 int i, index, count; 1109 ubyte[17] huff_num; 1110 ubyte[256] huff_val; 1111 1112 uint num_left = get_bits(16); 1113 1114 if (num_left < 2) 1115 stop_decoding(JPGD_BAD_DHT_MARKER); 1116 1117 num_left -= 2; 1118 1119 while (num_left) 1120 { 1121 index = get_bits(8); 1122 1123 huff_num.ptr[0] = 0; 1124 1125 count = 0; 1126 1127 for (i = 1; i <= 16; i++) 1128 { 1129 huff_num.ptr[i] = cast(ubyte)(get_bits(8)); 1130 count += huff_num.ptr[i]; 1131 } 1132 1133 if (count > 255) 1134 stop_decoding(JPGD_BAD_DHT_COUNTS); 1135 1136 for (i = 0; i < count; i++) 1137 huff_val.ptr[i] = cast(ubyte)(get_bits(8)); 1138 1139 i = 1 + 16 + count; 1140 1141 if (num_left < cast(uint)i) 1142 stop_decoding(JPGD_BAD_DHT_MARKER); 1143 1144 num_left -= i; 1145 1146 if ((index & 0x10) > 0x10) 1147 stop_decoding(JPGD_BAD_DHT_INDEX); 1148 1149 index = (index & 0x0F) + ((index & 0x10) >> 4) * (JPGD_MAX_HUFF_TABLES >> 1); 1150 1151 if (index >= JPGD_MAX_HUFF_TABLES) 1152 stop_decoding(JPGD_BAD_DHT_INDEX); 1153 1154 if (!m_huff_num.ptr[index]) 1155 m_huff_num.ptr[index] = cast(ubyte*)alloc(17); 1156 1157 if (!m_huff_val.ptr[index]) 1158 m_huff_val.ptr[index] = cast(ubyte*)alloc(256); 1159 1160 m_huff_ac.ptr[index] = (index & 0x10) != 0; 1161 memcpy(m_huff_num.ptr[index], huff_num.ptr, 17); 1162 memcpy(m_huff_val.ptr[index], huff_val.ptr, 256); 1163 } 1164 } 1165 1166 // Read a quantization table. 1167 void read_dqt_marker () { 1168 int n, i, prec; 1169 uint num_left; 1170 uint temp; 1171 1172 num_left = get_bits(16); 1173 1174 if (num_left < 2) 1175 stop_decoding(JPGD_BAD_DQT_MARKER); 1176 1177 num_left -= 2; 1178 1179 while (num_left) 1180 { 1181 n = get_bits(8); 1182 prec = n >> 4; 1183 n &= 0x0F; 1184 1185 if (n >= JPGD_MAX_QUANT_TABLES) 1186 stop_decoding(JPGD_BAD_DQT_TABLE); 1187 1188 if (!m_quant.ptr[n]) 1189 m_quant.ptr[n] = cast(jpgd_quant_t*)alloc(64 * jpgd_quant_t.sizeof); 1190 1191 // read quantization entries, in zag order 1192 for (i = 0; i < 64; i++) 1193 { 1194 temp = get_bits(8); 1195 1196 if (prec) 1197 temp = (temp << 8) + get_bits(8); 1198 1199 m_quant.ptr[n][i] = cast(jpgd_quant_t)(temp); 1200 } 1201 1202 i = 64 + 1; 1203 1204 if (prec) 1205 i += 64; 1206 1207 if (num_left < cast(uint)i) 1208 stop_decoding(JPGD_BAD_DQT_LENGTH); 1209 1210 num_left -= i; 1211 } 1212 } 1213 1214 // Read the start of frame (SOF) marker. 1215 void read_sof_marker () { 1216 int i; 1217 uint num_left; 1218 1219 num_left = get_bits(16); 1220 1221 if (get_bits(8) != 8) /* precision: sorry, only 8-bit precision is supported right now */ 1222 stop_decoding(JPGD_BAD_PRECISION); 1223 1224 m_image_y_size = get_bits(16); 1225 1226 if ((m_image_y_size < 1) || (m_image_y_size > JPGD_MAX_HEIGHT)) 1227 stop_decoding(JPGD_BAD_HEIGHT); 1228 1229 m_image_x_size = get_bits(16); 1230 1231 if ((m_image_x_size < 1) || (m_image_x_size > JPGD_MAX_WIDTH)) 1232 stop_decoding(JPGD_BAD_WIDTH); 1233 1234 m_comps_in_frame = get_bits(8); 1235 1236 if (m_comps_in_frame > JPGD_MAX_COMPONENTS) 1237 stop_decoding(JPGD_TOO_MANY_COMPONENTS); 1238 1239 if (num_left != cast(uint)(m_comps_in_frame * 3 + 8)) 1240 stop_decoding(JPGD_BAD_SOF_LENGTH); 1241 1242 for (i = 0; i < m_comps_in_frame; i++) 1243 { 1244 m_comp_ident.ptr[i] = get_bits(8); 1245 m_comp_h_samp.ptr[i] = get_bits(4); 1246 m_comp_v_samp.ptr[i] = get_bits(4); 1247 m_comp_quant.ptr[i] = get_bits(8); 1248 } 1249 } 1250 1251 // Used to skip unrecognized markers. 1252 void skip_variable_marker () { 1253 uint num_left; 1254 1255 num_left = get_bits(16); 1256 1257 if (num_left < 2) 1258 stop_decoding(JPGD_BAD_VARIABLE_MARKER); 1259 1260 num_left -= 2; 1261 1262 while (num_left) 1263 { 1264 get_bits(8); 1265 num_left--; 1266 } 1267 } 1268 1269 // Read a define restart interval (DRI) marker. 1270 void read_dri_marker () { 1271 if (get_bits(16) != 4) 1272 stop_decoding(JPGD_BAD_DRI_LENGTH); 1273 1274 m_restart_interval = get_bits(16); 1275 } 1276 1277 // Read a start of scan (SOS) marker. 1278 void read_sos_marker () { 1279 uint num_left; 1280 int i, ci, n, c, cc; 1281 1282 num_left = get_bits(16); 1283 1284 n = get_bits(8); 1285 1286 m_comps_in_scan = n; 1287 1288 num_left -= 3; 1289 1290 if ( (num_left != cast(uint)(n * 2 + 3)) || (n < 1) || (n > JPGD_MAX_COMPS_IN_SCAN) ) 1291 stop_decoding(JPGD_BAD_SOS_LENGTH); 1292 1293 for (i = 0; i < n; i++) 1294 { 1295 cc = get_bits(8); 1296 c = get_bits(8); 1297 num_left -= 2; 1298 1299 for (ci = 0; ci < m_comps_in_frame; ci++) 1300 if (cc == m_comp_ident.ptr[ci]) 1301 break; 1302 1303 if (ci >= m_comps_in_frame) 1304 stop_decoding(JPGD_BAD_SOS_COMP_ID); 1305 1306 m_comp_list.ptr[i] = ci; 1307 m_comp_dc_tab.ptr[ci] = (c >> 4) & 15; 1308 m_comp_ac_tab.ptr[ci] = (c & 15) + (JPGD_MAX_HUFF_TABLES >> 1); 1309 } 1310 1311 m_spectral_start = get_bits(8); 1312 m_spectral_end = get_bits(8); 1313 m_successive_high = get_bits(4); 1314 m_successive_low = get_bits(4); 1315 1316 if (!m_progressive_flag) 1317 { 1318 m_spectral_start = 0; 1319 m_spectral_end = 63; 1320 } 1321 1322 num_left -= 3; 1323 1324 /* read past whatever is num_left */ 1325 while (num_left) 1326 { 1327 get_bits(8); 1328 num_left--; 1329 } 1330 } 1331 1332 // Finds the next marker. 1333 int next_marker () { 1334 uint c, bytes; 1335 1336 bytes = 0; 1337 1338 do 1339 { 1340 do 1341 { 1342 bytes++; 1343 c = get_bits(8); 1344 } while (c != 0xFF); 1345 1346 do 1347 { 1348 c = get_bits(8); 1349 } while (c == 0xFF); 1350 1351 } while (c == 0); 1352 1353 // If bytes > 0 here, there where extra bytes before the marker (not good). 1354 1355 return c; 1356 } 1357 1358 // Process markers. Returns when an SOFx, SOI, EOI, or SOS marker is 1359 // encountered. 1360 int process_markers () { 1361 int c; 1362 1363 for ( ; ; ) { 1364 c = next_marker(); 1365 1366 switch (c) 1367 { 1368 case M_SOF0: 1369 case M_SOF1: 1370 case M_SOF2: 1371 case M_SOF3: 1372 case M_SOF5: 1373 case M_SOF6: 1374 case M_SOF7: 1375 //case M_JPG: 1376 case M_SOF9: 1377 case M_SOF10: 1378 case M_SOF11: 1379 case M_SOF13: 1380 case M_SOF14: 1381 case M_SOF15: 1382 case M_SOI: 1383 case M_EOI: 1384 case M_SOS: 1385 return c; 1386 case M_DHT: 1387 read_dht_marker(); 1388 break; 1389 // No arithmitic support - dumb patents! 1390 case M_DAC: 1391 stop_decoding(JPGD_NO_ARITHMITIC_SUPPORT); 1392 break; 1393 case M_DQT: 1394 read_dqt_marker(); 1395 break; 1396 case M_DRI: 1397 read_dri_marker(); 1398 break; 1399 1400 case M_APP0: 1401 uint num_left; 1402 1403 num_left = get_bits(16); 1404 1405 if (num_left < 7) 1406 stop_decoding(JPGD_BAD_VARIABLE_MARKER); 1407 1408 num_left -= 2; 1409 1410 ubyte[5] jfif_id; 1411 foreach(i; 0..5) 1412 jfif_id[i] = cast(ubyte) get_bits(8); 1413 1414 num_left -= 5; 1415 static immutable ubyte[5] JFIF = [0x4A, 0x46, 0x49, 0x46, 0x00]; 1416 if (jfif_id == JFIF && num_left >= 7) 1417 { 1418 // skip version 1419 get_bits(16); 1420 uint units = get_bits(8); 1421 int Xdensity = get_bits(16); 1422 int Ydensity = get_bits(16); 1423 num_left -= 7; 1424 1425 m_pixelAspectRatio = (Xdensity/cast(double)Ydensity); 1426 1427 switch (units) 1428 { 1429 case 0: // no units, just a ratio 1430 m_pixelsPerInchX = -1; 1431 m_pixelsPerInchY = -1; 1432 break; 1433 1434 case 1: // dot per inch 1435 m_pixelsPerInchX = Xdensity; 1436 m_pixelsPerInchY = Ydensity; 1437 break; 1438 1439 case 2: // dot per cm 1440 m_pixelsPerInchX = convertInchesToMeters(Xdensity * 100.0f); 1441 m_pixelsPerInchY = convertInchesToMeters(Ydensity * 100.0f); 1442 break; 1443 default: 1444 } 1445 } 1446 1447 // skip rests of chunk 1448 1449 while (num_left) 1450 { 1451 get_bits(8); 1452 num_left--; 1453 } 1454 break; 1455 1456 case M_APP0+1: // possibly EXIF data 1457 1458 uint num_left; 1459 num_left = get_bits(16); 1460 1461 if (num_left < 2) 1462 stop_decoding(JPGD_BAD_VARIABLE_MARKER); 1463 num_left -= 2; 1464 1465 ubyte[] exifData = (cast(ubyte*) malloc(num_left))[0..num_left]; 1466 scope(exit) free(exifData.ptr); 1467 1468 foreach(i; 0..num_left) 1469 exifData[i] = cast(ubyte)(get_bits(8)); 1470 1471 const(ubyte)* s = exifData.ptr; 1472 1473 ubyte[6] exif_id; 1474 foreach(i; 0..6) 1475 exif_id[i] = read_ubyte(s); 1476 1477 const(ubyte)* remainExifData = s; 1478 1479 static immutable ubyte[6] ExifIdentifierCode = [0x45, 0x78, 0x69, 0x66, 0x00, 0x00]; // "Exif\0\0" 1480 if (exif_id == ExifIdentifierCode) 1481 { 1482 // See EXIF specification: http://www.cipa.jp/std/documents/e/DC-008-2012_E.pdf 1483 1484 const(ubyte)* tiffFile = s; // save exif chunk from "start of TIFF file" 1485 1486 ushort byteOrder = read_ushort_BE(s); 1487 if (byteOrder != 0x4949 && byteOrder != 0x4D4D) 1488 stop_decoding(JPGD_DECODE_ERROR); 1489 bool littleEndian = (byteOrder == 0x4949); 1490 1491 ushort version_ = littleEndian ? read_ushort_LE(s) : read_ushort_BE(s); 1492 if (version_ != 42) 1493 stop_decoding(JPGD_DECODE_ERROR); 1494 1495 uint offset = littleEndian ? read_uint_LE(s) : read_uint_BE(s); 1496 1497 double resolutionX = 72; 1498 double resolutionY = 72; 1499 int unit = 2; 1500 1501 // parse all IFDs 1502 while(offset != 0) 1503 { 1504 if (offset > exifData.length) 1505 stop_decoding(JPGD_DECODE_ERROR); 1506 const(ubyte)* pIFD = tiffFile + offset; 1507 ushort numEntries = littleEndian ? read_ushort_LE(pIFD) : read_ushort_BE(pIFD); 1508 1509 foreach(entry; 0..numEntries) 1510 { 1511 ushort tag = littleEndian ? read_ushort_LE(pIFD) : read_ushort_BE(pIFD); 1512 ushort type = littleEndian ? read_ushort_LE(pIFD) : read_ushort_BE(pIFD); 1513 uint count = littleEndian ? read_uint_LE(pIFD) : read_uint_BE(pIFD); 1514 uint valueOffset = littleEndian ? read_uint_LE(pIFD) : read_uint_BE(pIFD); 1515 1516 if (tag == 282 || tag == 283) // XResolution 1517 { 1518 const(ubyte)* tagData = tiffFile + valueOffset; 1519 double num = littleEndian ? read_uint_LE(tagData) : read_uint_BE(tagData); 1520 double denom = littleEndian ? read_uint_LE(tagData) : read_uint_BE(tagData); 1521 double frac = num / denom; 1522 if (tag == 282) 1523 resolutionX = frac; 1524 else 1525 resolutionY = frac; 1526 } 1527 1528 if (tag == 296) // unit 1529 unit = valueOffset; 1530 } 1531 offset = littleEndian ? read_uint_LE(pIFD) : read_uint_BE(pIFD); 1532 } 1533 1534 if (unit == 2) // inches 1535 { 1536 m_pixelsPerInchX = resolutionX; 1537 m_pixelsPerInchY = resolutionY; 1538 m_pixelAspectRatio = resolutionX / resolutionY; 1539 } 1540 else if (unit == 3) // dots per cm 1541 { 1542 m_pixelsPerInchX = convertInchesToMeters(resolutionX * 100); 1543 m_pixelsPerInchY = convertInchesToMeters(resolutionY * 100); 1544 m_pixelAspectRatio = resolutionX / resolutionY; 1545 } 1546 } 1547 break; 1548 1549 case M_JPG: 1550 case M_RST0: /* no parameters */ 1551 case M_RST1: 1552 case M_RST2: 1553 case M_RST3: 1554 case M_RST4: 1555 case M_RST5: 1556 case M_RST6: 1557 case M_RST7: 1558 case M_TEM: 1559 stop_decoding(JPGD_UNEXPECTED_MARKER); 1560 break; 1561 default: /* must be DNL, DHP, EXP, APPn, JPGn, COM, or RESn or APP0 */ 1562 skip_variable_marker(); 1563 break; 1564 } 1565 } 1566 } 1567 1568 // Finds the start of image (SOI) marker. 1569 // This code is rather defensive: it only checks the first 512 bytes to avoid 1570 // false positives. 1571 void locate_soi_marker () { 1572 uint lastchar, thischar; 1573 uint bytesleft; 1574 1575 lastchar = get_bits(8); 1576 1577 thischar = get_bits(8); 1578 1579 /* ok if it's a normal JPEG file without a special header */ 1580 1581 if ((lastchar == 0xFF) && (thischar == M_SOI)) 1582 return; 1583 1584 bytesleft = 4096; //512; 1585 1586 for ( ; ; ) 1587 { 1588 if (--bytesleft == 0) 1589 stop_decoding(JPGD_NOT_JPEG); 1590 1591 lastchar = thischar; 1592 1593 thischar = get_bits(8); 1594 1595 if (lastchar == 0xFF) 1596 { 1597 if (thischar == M_SOI) 1598 break; 1599 else if (thischar == M_EOI) // get_bits will keep returning M_EOI if we read past the end 1600 stop_decoding(JPGD_NOT_JPEG); 1601 } 1602 } 1603 1604 // 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. 1605 thischar = (m_bit_buf >> 24) & 0xFF; 1606 1607 if (thischar != 0xFF) 1608 stop_decoding(JPGD_NOT_JPEG); 1609 } 1610 1611 // Find a start of frame (SOF) marker. 1612 void locate_sof_marker () { 1613 locate_soi_marker(); 1614 1615 int c = process_markers(); 1616 1617 switch (c) 1618 { 1619 case M_SOF2: 1620 m_progressive_flag = true; 1621 goto case; 1622 case M_SOF0: /* baseline DCT */ 1623 case M_SOF1: /* extended sequential DCT */ 1624 read_sof_marker(); 1625 break; 1626 case M_SOF9: /* Arithmitic coding */ 1627 stop_decoding(JPGD_NO_ARITHMITIC_SUPPORT); 1628 break; 1629 default: 1630 stop_decoding(JPGD_UNSUPPORTED_MARKER); 1631 break; 1632 } 1633 } 1634 1635 // Find a start of scan (SOS) marker. 1636 int locate_sos_marker () { 1637 int c; 1638 1639 c = process_markers(); 1640 1641 if (c == M_EOI) 1642 return false; 1643 else if (c != M_SOS) 1644 stop_decoding(JPGD_UNEXPECTED_MARKER); 1645 1646 read_sos_marker(); 1647 1648 return true; 1649 } 1650 1651 // Reset everything to default/uninitialized state. 1652 void initit (JpegStreamReadFunc rfn, void* userData) 1653 { 1654 m_pMem_blocks = null; 1655 m_error_code = JPGD_SUCCESS; 1656 m_ready_flag = false; 1657 m_image_x_size = m_image_y_size = 0; 1658 readfn = rfn; 1659 this.userData = userData; 1660 m_progressive_flag = false; 1661 1662 memset(m_huff_ac.ptr, 0, m_huff_ac.sizeof); 1663 memset(m_huff_num.ptr, 0, m_huff_num.sizeof); 1664 memset(m_huff_val.ptr, 0, m_huff_val.sizeof); 1665 memset(m_quant.ptr, 0, m_quant.sizeof); 1666 1667 m_scan_type = 0; 1668 m_comps_in_frame = 0; 1669 1670 memset(m_comp_h_samp.ptr, 0, m_comp_h_samp.sizeof); 1671 memset(m_comp_v_samp.ptr, 0, m_comp_v_samp.sizeof); 1672 memset(m_comp_quant.ptr, 0, m_comp_quant.sizeof); 1673 memset(m_comp_ident.ptr, 0, m_comp_ident.sizeof); 1674 memset(m_comp_h_blocks.ptr, 0, m_comp_h_blocks.sizeof); 1675 memset(m_comp_v_blocks.ptr, 0, m_comp_v_blocks.sizeof); 1676 1677 m_comps_in_scan = 0; 1678 memset(m_comp_list.ptr, 0, m_comp_list.sizeof); 1679 memset(m_comp_dc_tab.ptr, 0, m_comp_dc_tab.sizeof); 1680 memset(m_comp_ac_tab.ptr, 0, m_comp_ac_tab.sizeof); 1681 1682 m_spectral_start = 0; 1683 m_spectral_end = 0; 1684 m_successive_low = 0; 1685 m_successive_high = 0; 1686 m_max_mcu_x_size = 0; 1687 m_max_mcu_y_size = 0; 1688 m_blocks_per_mcu = 0; 1689 m_max_blocks_per_row = 0; 1690 m_mcus_per_row = 0; 1691 m_mcus_per_col = 0; 1692 m_expanded_blocks_per_component = 0; 1693 m_expanded_blocks_per_mcu = 0; 1694 m_expanded_blocks_per_row = 0; 1695 m_freq_domain_chroma_upsample = false; 1696 1697 memset(m_mcu_org.ptr, 0, m_mcu_org.sizeof); 1698 1699 m_total_lines_left = 0; 1700 m_mcu_lines_left = 0; 1701 m_real_dest_bytes_per_scan_line = 0; 1702 m_dest_bytes_per_scan_line = 0; 1703 m_dest_bytes_per_pixel = 0; 1704 1705 memset(m_pHuff_tabs.ptr, 0, m_pHuff_tabs.sizeof); 1706 1707 memset(m_dc_coeffs.ptr, 0, m_dc_coeffs.sizeof); 1708 memset(m_ac_coeffs.ptr, 0, m_ac_coeffs.sizeof); 1709 memset(m_block_y_mcu.ptr, 0, m_block_y_mcu.sizeof); 1710 1711 m_eob_run = 0; 1712 1713 memset(m_block_y_mcu.ptr, 0, m_block_y_mcu.sizeof); 1714 1715 m_pIn_buf_ofs = m_in_buf.ptr; 1716 m_in_buf_left = 0; 1717 m_eof_flag = false; 1718 m_tem_flag = 0; 1719 1720 memset(m_in_buf_pad_start.ptr, 0, m_in_buf_pad_start.sizeof); 1721 memset(m_in_buf.ptr, 0, m_in_buf.sizeof); 1722 memset(m_in_buf_pad_end.ptr, 0, m_in_buf_pad_end.sizeof); 1723 1724 m_restart_interval = 0; 1725 m_restarts_left = 0; 1726 m_next_restart_num = 0; 1727 1728 m_max_mcus_per_row = 0; 1729 m_max_blocks_per_mcu = 0; 1730 m_max_mcus_per_col = 0; 1731 1732 memset(m_last_dc_val.ptr, 0, m_last_dc_val.sizeof); 1733 m_pMCU_coefficients = null; 1734 m_pSample_buf = null; 1735 1736 m_total_bytes_read = 0; 1737 1738 m_pScan_line_0 = null; 1739 m_pScan_line_1 = null; 1740 1741 // Ready the input buffer. 1742 prep_in_buffer(); 1743 1744 // Prime the bit buffer. 1745 m_bits_left = 16; 1746 m_bit_buf = 0; 1747 1748 get_bits(16); 1749 get_bits(16); 1750 1751 for (int i = 0; i < JPGD_MAX_BLOCKS_PER_MCU; i++) 1752 m_mcu_block_max_zag.ptr[i] = 64; 1753 } 1754 1755 enum SCALEBITS = 16; 1756 enum ONE_HALF = (cast(int) 1 << (SCALEBITS-1)); 1757 enum FIX(float x) = (cast(int)((x) * (1L<<SCALEBITS) + 0.5f)); 1758 1759 // Create a few tables that allow us to quickly convert YCbCr to RGB. 1760 void create_look_ups () { 1761 for (int i = 0; i <= 255; i++) 1762 { 1763 int k = i - 128; 1764 m_crr.ptr[i] = ( FIX!(1.40200f) * k + ONE_HALF) >> SCALEBITS; 1765 m_cbb.ptr[i] = ( FIX!(1.77200f) * k + ONE_HALF) >> SCALEBITS; 1766 m_crg.ptr[i] = (-FIX!(0.71414f)) * k; 1767 m_cbg.ptr[i] = (-FIX!(0.34414f)) * k + ONE_HALF; 1768 } 1769 } 1770 1771 // This method throws back into the stream any bytes that where read 1772 // into the bit buffer during initial marker scanning. 1773 void fix_in_buffer () { 1774 // In case any 0xFF's where pulled into the buffer during marker scanning. 1775 assert((m_bits_left & 7) == 0); 1776 1777 if (m_bits_left == 16) 1778 stuff_char(cast(ubyte)(m_bit_buf & 0xFF)); 1779 1780 if (m_bits_left >= 8) 1781 stuff_char(cast(ubyte)((m_bit_buf >> 8) & 0xFF)); 1782 1783 stuff_char(cast(ubyte)((m_bit_buf >> 16) & 0xFF)); 1784 stuff_char(cast(ubyte)((m_bit_buf >> 24) & 0xFF)); 1785 1786 m_bits_left = 16; 1787 get_bits_no_markers(16); 1788 get_bits_no_markers(16); 1789 } 1790 1791 void transform_mcu (int mcu_row) { 1792 jpgd_block_t* pSrc_ptr = m_pMCU_coefficients; 1793 ubyte* pDst_ptr = m_pSample_buf + mcu_row * m_blocks_per_mcu * 64; 1794 1795 for (int mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++) 1796 { 1797 idct(pSrc_ptr, pDst_ptr, m_mcu_block_max_zag.ptr[mcu_block]); 1798 pSrc_ptr += 64; 1799 pDst_ptr += 64; 1800 } 1801 } 1802 1803 static immutable ubyte[64] s_max_rc = [ 1804 17, 18, 34, 50, 50, 51, 52, 52, 52, 68, 84, 84, 84, 84, 85, 86, 86, 86, 86, 86, 1805 102, 118, 118, 118, 118, 118, 118, 119, 120, 120, 120, 120, 120, 120, 120, 136, 1806 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 1807 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136 1808 ]; 1809 1810 void transform_mcu_expand (int mcu_row) { 1811 jpgd_block_t* pSrc_ptr = m_pMCU_coefficients; 1812 ubyte* pDst_ptr = m_pSample_buf + mcu_row * m_expanded_blocks_per_mcu * 64; 1813 1814 // Y IDCT 1815 int mcu_block; 1816 for (mcu_block = 0; mcu_block < m_expanded_blocks_per_component; mcu_block++) 1817 { 1818 idct(pSrc_ptr, pDst_ptr, m_mcu_block_max_zag.ptr[mcu_block]); 1819 pSrc_ptr += 64; 1820 pDst_ptr += 64; 1821 } 1822 1823 // Chroma IDCT, with upsampling 1824 jpgd_block_t[64] temp_block; 1825 1826 for (int i = 0; i < 2; i++) 1827 { 1828 DCT_Upsample.Matrix44 P, Q, R, S; 1829 1830 assert(m_mcu_block_max_zag.ptr[mcu_block] >= 1); 1831 assert(m_mcu_block_max_zag.ptr[mcu_block] <= 64); 1832 1833 int max_zag = m_mcu_block_max_zag.ptr[mcu_block++] - 1; 1834 if (max_zag <= 0) max_zag = 0; // should never happen, only here to shut up static analysis 1835 switch (s_max_rc.ptr[max_zag]) 1836 { 1837 case 1*16+1: 1838 DCT_Upsample.P_Q!(1, 1).calc(P, Q, pSrc_ptr); 1839 DCT_Upsample.R_S!(1, 1).calc(R, S, pSrc_ptr); 1840 break; 1841 case 1*16+2: 1842 DCT_Upsample.P_Q!(1, 2).calc(P, Q, pSrc_ptr); 1843 DCT_Upsample.R_S!(1, 2).calc(R, S, pSrc_ptr); 1844 break; 1845 case 2*16+2: 1846 DCT_Upsample.P_Q!(2, 2).calc(P, Q, pSrc_ptr); 1847 DCT_Upsample.R_S!(2, 2).calc(R, S, pSrc_ptr); 1848 break; 1849 case 3*16+2: 1850 DCT_Upsample.P_Q!(3, 2).calc(P, Q, pSrc_ptr); 1851 DCT_Upsample.R_S!(3, 2).calc(R, S, pSrc_ptr); 1852 break; 1853 case 3*16+3: 1854 DCT_Upsample.P_Q!(3, 3).calc(P, Q, pSrc_ptr); 1855 DCT_Upsample.R_S!(3, 3).calc(R, S, pSrc_ptr); 1856 break; 1857 case 3*16+4: 1858 DCT_Upsample.P_Q!(3, 4).calc(P, Q, pSrc_ptr); 1859 DCT_Upsample.R_S!(3, 4).calc(R, S, pSrc_ptr); 1860 break; 1861 case 4*16+4: 1862 DCT_Upsample.P_Q!(4, 4).calc(P, Q, pSrc_ptr); 1863 DCT_Upsample.R_S!(4, 4).calc(R, S, pSrc_ptr); 1864 break; 1865 case 5*16+4: 1866 DCT_Upsample.P_Q!(5, 4).calc(P, Q, pSrc_ptr); 1867 DCT_Upsample.R_S!(5, 4).calc(R, S, pSrc_ptr); 1868 break; 1869 case 5*16+5: 1870 DCT_Upsample.P_Q!(5, 5).calc(P, Q, pSrc_ptr); 1871 DCT_Upsample.R_S!(5, 5).calc(R, S, pSrc_ptr); 1872 break; 1873 case 5*16+6: 1874 DCT_Upsample.P_Q!(5, 6).calc(P, Q, pSrc_ptr); 1875 DCT_Upsample.R_S!(5, 6).calc(R, S, pSrc_ptr); 1876 break; 1877 case 6*16+6: 1878 DCT_Upsample.P_Q!(6, 6).calc(P, Q, pSrc_ptr); 1879 DCT_Upsample.R_S!(6, 6).calc(R, S, pSrc_ptr); 1880 break; 1881 case 7*16+6: 1882 DCT_Upsample.P_Q!(7, 6).calc(P, Q, pSrc_ptr); 1883 DCT_Upsample.R_S!(7, 6).calc(R, S, pSrc_ptr); 1884 break; 1885 case 7*16+7: 1886 DCT_Upsample.P_Q!(7, 7).calc(P, Q, pSrc_ptr); 1887 DCT_Upsample.R_S!(7, 7).calc(R, S, pSrc_ptr); 1888 break; 1889 case 7*16+8: 1890 DCT_Upsample.P_Q!(7, 8).calc(P, Q, pSrc_ptr); 1891 DCT_Upsample.R_S!(7, 8).calc(R, S, pSrc_ptr); 1892 break; 1893 case 8*16+8: 1894 DCT_Upsample.P_Q!(8, 8).calc(P, Q, pSrc_ptr); 1895 DCT_Upsample.R_S!(8, 8).calc(R, S, pSrc_ptr); 1896 break; 1897 default: 1898 assert(false); 1899 } 1900 1901 auto a = DCT_Upsample.Matrix44(P + Q); 1902 P -= Q; 1903 DCT_Upsample.Matrix44* b = &P; 1904 auto c = DCT_Upsample.Matrix44(R + S); 1905 R -= S; 1906 DCT_Upsample.Matrix44* d = &R; 1907 1908 DCT_Upsample.Matrix44.add_and_store(temp_block.ptr, a, c); 1909 idct_4x4(temp_block.ptr, pDst_ptr); 1910 pDst_ptr += 64; 1911 1912 DCT_Upsample.Matrix44.sub_and_store(temp_block.ptr, a, c); 1913 idct_4x4(temp_block.ptr, pDst_ptr); 1914 pDst_ptr += 64; 1915 1916 DCT_Upsample.Matrix44.add_and_store(temp_block.ptr, *b, *d); 1917 idct_4x4(temp_block.ptr, pDst_ptr); 1918 pDst_ptr += 64; 1919 1920 DCT_Upsample.Matrix44.sub_and_store(temp_block.ptr, *b, *d); 1921 idct_4x4(temp_block.ptr, pDst_ptr); 1922 pDst_ptr += 64; 1923 1924 pSrc_ptr += 64; 1925 } 1926 } 1927 1928 // Loads and dequantizes the next row of (already decoded) coefficients. 1929 // Progressive images only. 1930 void load_next_row () { 1931 int i; 1932 jpgd_block_t *p; 1933 jpgd_quant_t *q; 1934 int mcu_row, mcu_block, row_block = 0; 1935 int component_num, component_id; 1936 int[JPGD_MAX_COMPONENTS] block_x_mcu; 1937 1938 memset(block_x_mcu.ptr, 0, JPGD_MAX_COMPONENTS * int.sizeof); 1939 1940 for (mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++) 1941 { 1942 int block_x_mcu_ofs = 0, block_y_mcu_ofs = 0; 1943 1944 for (mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++) 1945 { 1946 component_id = m_mcu_org.ptr[mcu_block]; 1947 q = m_quant.ptr[m_comp_quant.ptr[component_id]]; 1948 1949 p = m_pMCU_coefficients + 64 * mcu_block; 1950 1951 jpgd_block_t* pAC = coeff_buf_getp(m_ac_coeffs.ptr[component_id], block_x_mcu.ptr[component_id] + block_x_mcu_ofs, m_block_y_mcu.ptr[component_id] + block_y_mcu_ofs); 1952 jpgd_block_t* pDC = coeff_buf_getp(m_dc_coeffs.ptr[component_id], block_x_mcu.ptr[component_id] + block_x_mcu_ofs, m_block_y_mcu.ptr[component_id] + block_y_mcu_ofs); 1953 p[0] = pDC[0]; 1954 memcpy(&p[1], &pAC[1], 63 * jpgd_block_t.sizeof); 1955 1956 for (i = 63; i > 0; i--) 1957 if (p[g_ZAG[i]]) 1958 break; 1959 1960 m_mcu_block_max_zag.ptr[mcu_block] = i + 1; 1961 1962 for ( ; i >= 0; i--) 1963 if (p[g_ZAG[i]]) 1964 p[g_ZAG[i]] = cast(jpgd_block_t)(p[g_ZAG[i]] * q[i]); 1965 1966 row_block++; 1967 1968 if (m_comps_in_scan == 1) 1969 block_x_mcu.ptr[component_id]++; 1970 else 1971 { 1972 if (++block_x_mcu_ofs == m_comp_h_samp.ptr[component_id]) 1973 { 1974 block_x_mcu_ofs = 0; 1975 1976 if (++block_y_mcu_ofs == m_comp_v_samp.ptr[component_id]) 1977 { 1978 block_y_mcu_ofs = 0; 1979 1980 block_x_mcu.ptr[component_id] += m_comp_h_samp.ptr[component_id]; 1981 } 1982 } 1983 } 1984 } 1985 1986 if (m_freq_domain_chroma_upsample) 1987 transform_mcu_expand(mcu_row); 1988 else 1989 transform_mcu(mcu_row); 1990 } 1991 1992 if (m_comps_in_scan == 1) 1993 m_block_y_mcu.ptr[m_comp_list.ptr[0]]++; 1994 else 1995 { 1996 for (component_num = 0; component_num < m_comps_in_scan; component_num++) 1997 { 1998 component_id = m_comp_list.ptr[component_num]; 1999 2000 m_block_y_mcu.ptr[component_id] += m_comp_v_samp.ptr[component_id]; 2001 } 2002 } 2003 } 2004 2005 // Restart interval processing. 2006 void process_restart () { 2007 int i; 2008 int c = 0; 2009 2010 // Align to a byte boundry 2011 // FIXME: Is this really necessary? get_bits_no_markers() never reads in markers! 2012 //get_bits_no_markers(m_bits_left & 7); 2013 2014 // Let's scan a little bit to find the marker, but not _too_ far. 2015 // 1536 is a "fudge factor" that determines how much to scan. 2016 for (i = 1536; i > 0; i--) 2017 if (get_char() == 0xFF) 2018 break; 2019 2020 if (i == 0) 2021 stop_decoding(JPGD_BAD_RESTART_MARKER); 2022 2023 for ( ; i > 0; i--) 2024 if ((c = get_char()) != 0xFF) 2025 break; 2026 2027 if (i == 0) 2028 stop_decoding(JPGD_BAD_RESTART_MARKER); 2029 2030 // Is it the expected marker? If not, something bad happened. 2031 if (c != (m_next_restart_num + M_RST0)) 2032 stop_decoding(JPGD_BAD_RESTART_MARKER); 2033 2034 // Reset each component's DC prediction values. 2035 memset(&m_last_dc_val, 0, m_comps_in_frame * uint.sizeof); 2036 2037 m_eob_run = 0; 2038 2039 m_restarts_left = m_restart_interval; 2040 2041 m_next_restart_num = (m_next_restart_num + 1) & 7; 2042 2043 // Get the bit buffer going again... 2044 2045 m_bits_left = 16; 2046 get_bits_no_markers(16); 2047 get_bits_no_markers(16); 2048 } 2049 2050 // Decodes and dequantizes the next row of coefficients. 2051 void decode_next_row () { 2052 int row_block = 0; 2053 2054 for (int mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++) 2055 { 2056 if ((m_restart_interval) && (m_restarts_left == 0)) 2057 process_restart(); 2058 2059 jpgd_block_t* p = m_pMCU_coefficients; 2060 for (int mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++, p += 64) 2061 { 2062 int component_id = m_mcu_org.ptr[mcu_block]; 2063 jpgd_quant_t* q = m_quant.ptr[m_comp_quant.ptr[component_id]]; 2064 2065 int r, s; 2066 s = huff_decode(m_pHuff_tabs.ptr[m_comp_dc_tab.ptr[component_id]], r); 2067 s = JPGD_HUFF_EXTEND(r, s); 2068 2069 m_last_dc_val.ptr[component_id] = (s += m_last_dc_val.ptr[component_id]); 2070 2071 p[0] = cast(jpgd_block_t)(s * q[0]); 2072 2073 int prev_num_set = m_mcu_block_max_zag.ptr[mcu_block]; 2074 2075 huff_tables *pH = m_pHuff_tabs.ptr[m_comp_ac_tab.ptr[component_id]]; 2076 2077 int k; 2078 for (k = 1; k < 64; k++) 2079 { 2080 int extra_bits; 2081 s = huff_decode(pH, extra_bits); 2082 2083 r = s >> 4; 2084 s &= 15; 2085 2086 if (s) 2087 { 2088 if (r) 2089 { 2090 if ((k + r) > 63) 2091 stop_decoding(JPGD_DECODE_ERROR); 2092 2093 if (k < prev_num_set) 2094 { 2095 int n = JPGD_MIN(r, prev_num_set - k); 2096 int kt = k; 2097 while (n--) 2098 p[g_ZAG[kt++]] = 0; 2099 } 2100 2101 k += r; 2102 } 2103 2104 s = JPGD_HUFF_EXTEND(extra_bits, s); 2105 2106 assert(k < 64); 2107 2108 p[g_ZAG[k]] = cast(jpgd_block_t)( s * q[k] ); // dequantize 2109 } 2110 else 2111 { 2112 if (r == 15) 2113 { 2114 if ((k + 16) > 64) 2115 stop_decoding(JPGD_DECODE_ERROR); 2116 2117 if (k < prev_num_set) 2118 { 2119 int n = JPGD_MIN(16, prev_num_set - k); 2120 int kt = k; 2121 while (n--) 2122 { 2123 assert(kt <= 63); 2124 p[g_ZAG[kt++]] = 0; 2125 } 2126 } 2127 2128 k += 16 - 1; // - 1 because the loop counter is k 2129 assert(p[g_ZAG[k]] == 0); 2130 } 2131 else 2132 break; 2133 } 2134 } 2135 2136 if (k < prev_num_set) 2137 { 2138 int kt = k; 2139 while (kt < prev_num_set) 2140 p[g_ZAG[kt++]] = 0; 2141 } 2142 2143 m_mcu_block_max_zag.ptr[mcu_block] = k; 2144 2145 row_block++; 2146 } 2147 2148 if (m_freq_domain_chroma_upsample) 2149 transform_mcu_expand(mcu_row); 2150 else 2151 transform_mcu(mcu_row); 2152 2153 m_restarts_left--; 2154 } 2155 } 2156 2157 // YCbCr H1V1 (1x1:1:1, 3 m_blocks per MCU) to RGB 2158 void H1V1Convert () { 2159 int row = m_max_mcu_y_size - m_mcu_lines_left; 2160 ubyte *d = m_pScan_line_0; 2161 ubyte *s = m_pSample_buf + row * 8; 2162 2163 for (int i = m_max_mcus_per_row; i > 0; i--) 2164 { 2165 for (int j = 0; j < 8; j++) 2166 { 2167 int y = s[j]; 2168 int cb = s[64+j]; 2169 int cr = s[128+j]; 2170 2171 2172 __m128i zero = _mm_setzero_si128(); 2173 __m128i A = _mm_setr_epi32(y + m_crr.ptr[cr], 2174 y + ((m_crg.ptr[cr] + m_cbg.ptr[cb]) >> 16), 2175 y + m_cbb.ptr[cb], 2176 255); 2177 A = _mm_packs_epi32(A, zero); 2178 A = _mm_packus_epi16(A, zero); 2179 _mm_storeu_si32(&d[0], A); 2180 d += 4; 2181 } 2182 2183 s += 64*3; 2184 } 2185 } 2186 2187 // YCbCr H2V1 (2x1:1:1, 4 m_blocks per MCU) to RGB 2188 void H2V1Convert () 2189 { 2190 int row = m_max_mcu_y_size - m_mcu_lines_left; 2191 ubyte *d0 = m_pScan_line_0; 2192 ubyte *y = m_pSample_buf + row * 8; 2193 ubyte *c = m_pSample_buf + 2*64 + row * 8; 2194 2195 for (int i = m_max_mcus_per_row; i > 0; i--) 2196 { 2197 for (int l = 0; l < 2; l++) 2198 { 2199 for (int j = 0; j < 4; j++) 2200 { 2201 int cb = c[0]; 2202 int cr = c[64]; 2203 2204 int rc = m_crr.ptr[cr]; 2205 int gc = ((m_crg.ptr[cr] + m_cbg.ptr[cb]) >> 16); 2206 int bc = m_cbb.ptr[cb]; 2207 2208 int yy = y[j<<1]; 2209 d0[0] = clamp(yy+rc); 2210 d0[1] = clamp(yy+gc); 2211 d0[2] = clamp(yy+bc); 2212 d0[3] = 255; 2213 2214 yy = y[(j<<1)+1]; 2215 d0[4] = clamp(yy+rc); 2216 d0[5] = clamp(yy+gc); 2217 d0[6] = clamp(yy+bc); 2218 d0[7] = 255; 2219 2220 d0 += 8; 2221 2222 c++; 2223 } 2224 y += 64; 2225 } 2226 2227 y += 64*4 - 64*2; 2228 c += 64*4 - 8; 2229 } 2230 } 2231 2232 // YCbCr H2V1 (1x2:1:1, 4 m_blocks per MCU) to RGB 2233 void H1V2Convert () { 2234 int row = m_max_mcu_y_size - m_mcu_lines_left; 2235 ubyte *d0 = m_pScan_line_0; 2236 ubyte *d1 = m_pScan_line_1; 2237 ubyte *y; 2238 ubyte *c; 2239 2240 if (row < 8) 2241 y = m_pSample_buf + row * 8; 2242 else 2243 y = m_pSample_buf + 64*1 + (row & 7) * 8; 2244 2245 c = m_pSample_buf + 64*2 + (row >> 1) * 8; 2246 2247 for (int i = m_max_mcus_per_row; i > 0; i--) 2248 { 2249 for (int j = 0; j < 8; j++) 2250 { 2251 int cb = c[0+j]; 2252 int cr = c[64+j]; 2253 2254 int rc = m_crr.ptr[cr]; 2255 int gc = ((m_crg.ptr[cr] + m_cbg.ptr[cb]) >> 16); 2256 int bc = m_cbb.ptr[cb]; 2257 2258 int yy = y[j]; 2259 d0[0] = clamp(yy+rc); 2260 d0[1] = clamp(yy+gc); 2261 d0[2] = clamp(yy+bc); 2262 d0[3] = 255; 2263 2264 yy = y[8+j]; 2265 d1[0] = clamp(yy+rc); 2266 d1[1] = clamp(yy+gc); 2267 d1[2] = clamp(yy+bc); 2268 d1[3] = 255; 2269 2270 d0 += 4; 2271 d1 += 4; 2272 } 2273 2274 y += 64*4; 2275 c += 64*4; 2276 } 2277 } 2278 2279 // YCbCr H2V2 (2x2:1:1, 6 m_blocks per MCU) to RGB 2280 void H2V2Convert () { 2281 int row = m_max_mcu_y_size - m_mcu_lines_left; 2282 ubyte *d0 = m_pScan_line_0; 2283 ubyte *d1 = m_pScan_line_1; 2284 ubyte *y; 2285 ubyte *c; 2286 2287 if (row < 8) 2288 y = m_pSample_buf + row * 8; 2289 else 2290 y = m_pSample_buf + 64*2 + (row & 7) * 8; 2291 2292 c = m_pSample_buf + 64*4 + (row >> 1) * 8; 2293 2294 for (int i = m_max_mcus_per_row; i > 0; i--) 2295 { 2296 for (int l = 0; l < 2; l++) 2297 { 2298 for (int j = 0; j < 8; j += 2) 2299 { 2300 int cb = c[0]; 2301 int cr = c[64]; 2302 2303 int rc = m_crr.ptr[cr]; 2304 int gc = ((m_crg.ptr[cr] + m_cbg.ptr[cb]) >> 16); 2305 int bc = m_cbb.ptr[cb]; 2306 2307 int yy = y[j]; 2308 d0[0] = clamp(yy+rc); 2309 d0[1] = clamp(yy+gc); 2310 d0[2] = clamp(yy+bc); 2311 d0[3] = 255; 2312 2313 yy = y[j+1]; 2314 d0[4] = clamp(yy+rc); 2315 d0[5] = clamp(yy+gc); 2316 d0[6] = clamp(yy+bc); 2317 d0[7] = 255; 2318 2319 yy = y[j+8]; 2320 d1[0] = clamp(yy+rc); 2321 d1[1] = clamp(yy+gc); 2322 d1[2] = clamp(yy+bc); 2323 d1[3] = 255; 2324 2325 yy = y[j+8+1]; 2326 d1[4] = clamp(yy+rc); 2327 d1[5] = clamp(yy+gc); 2328 d1[6] = clamp(yy+bc); 2329 d1[7] = 255; 2330 2331 d0 += 8; 2332 d1 += 8; 2333 2334 c++; 2335 } 2336 y += 64; 2337 } 2338 2339 y += 64*6 - 64*2; 2340 c += 64*6 - 8; 2341 } 2342 } 2343 2344 // Y (1 block per MCU) to 8-bit grayscale 2345 void gray_convert () { 2346 int row = m_max_mcu_y_size - m_mcu_lines_left; 2347 ubyte *d = m_pScan_line_0; 2348 ubyte *s = m_pSample_buf + row * 8; 2349 2350 for (int i = m_max_mcus_per_row; i > 0; i--) 2351 { 2352 *cast(uint*)d = *cast(uint*)s; 2353 *cast(uint*)(&d[4]) = *cast(uint*)(&s[4]); 2354 2355 s += 64; 2356 d += 8; 2357 } 2358 } 2359 2360 2361 void expanded_convert () 2362 { 2363 int row = m_max_mcu_y_size - m_mcu_lines_left; 2364 2365 ubyte* Py = m_pSample_buf + (row / 8) * 64 * m_comp_h_samp.ptr[0] + (row & 7) * 8; 2366 2367 ubyte* d = m_pScan_line_0; 2368 2369 for (int i = m_max_mcus_per_row; i > 0; i--) 2370 { 2371 for (int k = 0; k < m_max_mcu_x_size; k += 8) 2372 { 2373 immutable int Y_ofs = k * 8; 2374 immutable int Cb_ofs = Y_ofs + 64 * m_expanded_blocks_per_component; 2375 immutable int Cr_ofs = Y_ofs + 64 * m_expanded_blocks_per_component * 2; 2376 for (int j = 0; j < 8; j++) 2377 { 2378 int y = Py[Y_ofs + j]; 2379 int cb = Py[Cb_ofs + j]; 2380 int cr = Py[Cr_ofs + j]; 2381 2382 __m128i zero = _mm_setzero_si128(); 2383 __m128i A = _mm_setr_epi32(y + m_crr.ptr[cr], 2384 y + ((m_crg.ptr[cr] + m_cbg.ptr[cb]) >> 16), 2385 y + m_cbb.ptr[cb], 2386 255); 2387 A = _mm_packs_epi32(A, zero); 2388 A = _mm_packus_epi16(A, zero); 2389 _mm_storeu_si32(&d[0], A); 2390 d += 4; 2391 } 2392 } 2393 2394 Py += 64 * m_expanded_blocks_per_mcu; 2395 } 2396 } 2397 2398 // Find end of image (EOI) marker, so we can return to the user the exact size of the input stream. 2399 void find_eoi () { 2400 if (!m_progressive_flag) 2401 { 2402 // Attempt to read the EOI marker. 2403 //get_bits_no_markers(m_bits_left & 7); 2404 2405 // Prime the bit buffer 2406 m_bits_left = 16; 2407 get_bits(16); 2408 get_bits(16); 2409 2410 // The next marker _should_ be EOI 2411 process_markers(); 2412 } 2413 2414 m_total_bytes_read -= m_in_buf_left; 2415 } 2416 2417 // Creates the tables needed for efficient Huffman decoding. 2418 void make_huff_table (int index, huff_tables *pH) { 2419 int p, i, l, si; 2420 ubyte[257] huffsize; 2421 uint[257] huffcode; 2422 uint code; 2423 uint subtree; 2424 int code_size; 2425 int lastp; 2426 int nextfreeentry; 2427 int currententry; 2428 2429 pH.ac_table = m_huff_ac.ptr[index] != 0; 2430 2431 p = 0; 2432 2433 for (l = 1; l <= 16; l++) 2434 { 2435 for (i = 1; i <= m_huff_num.ptr[index][l]; i++) 2436 huffsize.ptr[p++] = cast(ubyte)(l); 2437 } 2438 2439 huffsize.ptr[p] = 0; 2440 2441 lastp = p; 2442 2443 code = 0; 2444 si = huffsize.ptr[0]; 2445 p = 0; 2446 2447 while (huffsize.ptr[p]) 2448 { 2449 while (huffsize.ptr[p] == si) 2450 { 2451 huffcode.ptr[p++] = code; 2452 code++; 2453 } 2454 2455 code <<= 1; 2456 si++; 2457 } 2458 2459 memset(pH.look_up.ptr, 0, pH.look_up.sizeof); 2460 memset(pH.look_up2.ptr, 0, pH.look_up2.sizeof); 2461 memset(pH.tree.ptr, 0, pH.tree.sizeof); 2462 memset(pH.code_size.ptr, 0, pH.code_size.sizeof); 2463 2464 nextfreeentry = -1; 2465 2466 p = 0; 2467 2468 while (p < lastp) 2469 { 2470 i = m_huff_val.ptr[index][p]; 2471 code = huffcode.ptr[p]; 2472 code_size = huffsize.ptr[p]; 2473 2474 pH.code_size.ptr[i] = cast(ubyte)(code_size); 2475 2476 if (code_size <= 8) 2477 { 2478 code <<= (8 - code_size); 2479 2480 for (l = 1 << (8 - code_size); l > 0; l--) 2481 { 2482 assert(i < 256); 2483 2484 pH.look_up.ptr[code] = i; 2485 2486 bool has_extrabits = false; 2487 int extra_bits = 0; 2488 int num_extra_bits = i & 15; 2489 2490 int bits_to_fetch = code_size; 2491 if (num_extra_bits) 2492 { 2493 int total_codesize = code_size + num_extra_bits; 2494 if (total_codesize <= 8) 2495 { 2496 has_extrabits = true; 2497 extra_bits = ((1 << num_extra_bits) - 1) & (code >> (8 - total_codesize)); 2498 assert(extra_bits <= 0x7FFF); 2499 bits_to_fetch += num_extra_bits; 2500 } 2501 } 2502 2503 if (!has_extrabits) 2504 pH.look_up2.ptr[code] = i | (bits_to_fetch << 8); 2505 else 2506 pH.look_up2.ptr[code] = i | 0x8000 | (extra_bits << 16) | (bits_to_fetch << 8); 2507 2508 code++; 2509 } 2510 } 2511 else 2512 { 2513 subtree = (code >> (code_size - 8)) & 0xFF; 2514 2515 currententry = pH.look_up.ptr[subtree]; 2516 2517 if (currententry == 0) 2518 { 2519 pH.look_up.ptr[subtree] = currententry = nextfreeentry; 2520 pH.look_up2.ptr[subtree] = currententry = nextfreeentry; 2521 2522 nextfreeentry -= 2; 2523 } 2524 2525 code <<= (16 - (code_size - 8)); 2526 2527 for (l = code_size; l > 9; l--) 2528 { 2529 if ((code & 0x8000) == 0) 2530 currententry--; 2531 2532 if (pH.tree.ptr[-currententry - 1] == 0) 2533 { 2534 pH.tree.ptr[-currententry - 1] = nextfreeentry; 2535 2536 currententry = nextfreeentry; 2537 2538 nextfreeentry -= 2; 2539 } 2540 else 2541 currententry = pH.tree.ptr[-currententry - 1]; 2542 2543 code <<= 1; 2544 } 2545 2546 if ((code & 0x8000) == 0) 2547 currententry--; 2548 2549 pH.tree.ptr[-currententry - 1] = i; 2550 } 2551 2552 p++; 2553 } 2554 } 2555 2556 // Verifies the quantization tables needed for this scan are available. 2557 void check_quant_tables () { 2558 for (int i = 0; i < m_comps_in_scan; i++) 2559 if (m_quant.ptr[m_comp_quant.ptr[m_comp_list.ptr[i]]] == null) 2560 stop_decoding(JPGD_UNDEFINED_QUANT_TABLE); 2561 } 2562 2563 // Verifies that all the Huffman tables needed for this scan are available. 2564 void check_huff_tables () { 2565 for (int i = 0; i < m_comps_in_scan; i++) 2566 { 2567 if ((m_spectral_start == 0) && (m_huff_num.ptr[m_comp_dc_tab.ptr[m_comp_list.ptr[i]]] == null)) 2568 stop_decoding(JPGD_UNDEFINED_HUFF_TABLE); 2569 2570 if ((m_spectral_end > 0) && (m_huff_num.ptr[m_comp_ac_tab.ptr[m_comp_list.ptr[i]]] == null)) 2571 stop_decoding(JPGD_UNDEFINED_HUFF_TABLE); 2572 } 2573 2574 for (int i = 0; i < JPGD_MAX_HUFF_TABLES; i++) 2575 if (m_huff_num.ptr[i]) 2576 { 2577 if (!m_pHuff_tabs.ptr[i]) 2578 m_pHuff_tabs.ptr[i] = cast(huff_tables*)alloc(huff_tables.sizeof); 2579 2580 make_huff_table(i, m_pHuff_tabs.ptr[i]); 2581 } 2582 } 2583 2584 // Determines the component order inside each MCU. 2585 // Also calcs how many MCU's are on each row, etc. 2586 void calc_mcu_block_order () { 2587 int component_num, component_id; 2588 int max_h_samp = 0, max_v_samp = 0; 2589 2590 for (component_id = 0; component_id < m_comps_in_frame; component_id++) 2591 { 2592 if (m_comp_h_samp.ptr[component_id] > max_h_samp) 2593 max_h_samp = m_comp_h_samp.ptr[component_id]; 2594 2595 if (m_comp_v_samp.ptr[component_id] > max_v_samp) 2596 max_v_samp = m_comp_v_samp.ptr[component_id]; 2597 } 2598 2599 for (component_id = 0; component_id < m_comps_in_frame; component_id++) 2600 { 2601 m_comp_h_blocks.ptr[component_id] = ((((m_image_x_size * m_comp_h_samp.ptr[component_id]) + (max_h_samp - 1)) / max_h_samp) + 7) / 8; 2602 m_comp_v_blocks.ptr[component_id] = ((((m_image_y_size * m_comp_v_samp.ptr[component_id]) + (max_v_samp - 1)) / max_v_samp) + 7) / 8; 2603 } 2604 2605 if (m_comps_in_scan == 1) 2606 { 2607 m_mcus_per_row = m_comp_h_blocks.ptr[m_comp_list.ptr[0]]; 2608 m_mcus_per_col = m_comp_v_blocks.ptr[m_comp_list.ptr[0]]; 2609 } 2610 else 2611 { 2612 m_mcus_per_row = (((m_image_x_size + 7) / 8) + (max_h_samp - 1)) / max_h_samp; 2613 m_mcus_per_col = (((m_image_y_size + 7) / 8) + (max_v_samp - 1)) / max_v_samp; 2614 } 2615 2616 if (m_comps_in_scan == 1) 2617 { 2618 m_mcu_org.ptr[0] = m_comp_list.ptr[0]; 2619 2620 m_blocks_per_mcu = 1; 2621 } 2622 else 2623 { 2624 m_blocks_per_mcu = 0; 2625 2626 for (component_num = 0; component_num < m_comps_in_scan; component_num++) 2627 { 2628 int num_blocks; 2629 2630 component_id = m_comp_list.ptr[component_num]; 2631 2632 num_blocks = m_comp_h_samp.ptr[component_id] * m_comp_v_samp.ptr[component_id]; 2633 2634 while (num_blocks--) 2635 m_mcu_org.ptr[m_blocks_per_mcu++] = component_id; 2636 } 2637 } 2638 } 2639 2640 // Starts a new scan. 2641 int init_scan () { 2642 if (!locate_sos_marker()) 2643 return false; 2644 2645 calc_mcu_block_order(); 2646 2647 check_huff_tables(); 2648 2649 check_quant_tables(); 2650 2651 memset(m_last_dc_val.ptr, 0, m_comps_in_frame * uint.sizeof); 2652 2653 m_eob_run = 0; 2654 2655 if (m_restart_interval) 2656 { 2657 m_restarts_left = m_restart_interval; 2658 m_next_restart_num = 0; 2659 } 2660 2661 fix_in_buffer(); 2662 2663 return true; 2664 } 2665 2666 // Starts a frame. Determines if the number of components or sampling factors 2667 // are supported. 2668 void init_frame () { 2669 int i; 2670 2671 if (m_comps_in_frame == 1) 2672 { 2673 if ((m_comp_h_samp.ptr[0] != 1) || (m_comp_v_samp.ptr[0] != 1)) 2674 stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS); 2675 2676 m_scan_type = JPGD_GRAYSCALE; 2677 m_max_blocks_per_mcu = 1; 2678 m_max_mcu_x_size = 8; 2679 m_max_mcu_y_size = 8; 2680 } 2681 else if (m_comps_in_frame == 3) 2682 { 2683 if ( ((m_comp_h_samp.ptr[1] != 1) || (m_comp_v_samp.ptr[1] != 1)) || 2684 ((m_comp_h_samp.ptr[2] != 1) || (m_comp_v_samp.ptr[2] != 1)) ) 2685 stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS); 2686 2687 if ((m_comp_h_samp.ptr[0] == 1) && (m_comp_v_samp.ptr[0] == 1)) 2688 { 2689 m_scan_type = JPGD_YH1V1; 2690 2691 m_max_blocks_per_mcu = 3; 2692 m_max_mcu_x_size = 8; 2693 m_max_mcu_y_size = 8; 2694 } 2695 else if ((m_comp_h_samp.ptr[0] == 2) && (m_comp_v_samp.ptr[0] == 1)) 2696 { 2697 m_scan_type = JPGD_YH2V1; 2698 m_max_blocks_per_mcu = 4; 2699 m_max_mcu_x_size = 16; 2700 m_max_mcu_y_size = 8; 2701 } 2702 else if ((m_comp_h_samp.ptr[0] == 1) && (m_comp_v_samp.ptr[0] == 2)) 2703 { 2704 m_scan_type = JPGD_YH1V2; 2705 m_max_blocks_per_mcu = 4; 2706 m_max_mcu_x_size = 8; 2707 m_max_mcu_y_size = 16; 2708 } 2709 else if ((m_comp_h_samp.ptr[0] == 2) && (m_comp_v_samp.ptr[0] == 2)) 2710 { 2711 m_scan_type = JPGD_YH2V2; 2712 m_max_blocks_per_mcu = 6; 2713 m_max_mcu_x_size = 16; 2714 m_max_mcu_y_size = 16; 2715 } 2716 else 2717 stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS); 2718 } 2719 else 2720 stop_decoding(JPGD_UNSUPPORTED_COLORSPACE); 2721 2722 m_max_mcus_per_row = (m_image_x_size + (m_max_mcu_x_size - 1)) / m_max_mcu_x_size; 2723 m_max_mcus_per_col = (m_image_y_size + (m_max_mcu_y_size - 1)) / m_max_mcu_y_size; 2724 2725 // These values are for the *destination* pixels: after conversion. 2726 if (m_scan_type == JPGD_GRAYSCALE) 2727 m_dest_bytes_per_pixel = 1; 2728 else 2729 m_dest_bytes_per_pixel = 4; 2730 2731 m_dest_bytes_per_scan_line = ((m_image_x_size + 15) & 0xFFF0) * m_dest_bytes_per_pixel; 2732 2733 m_real_dest_bytes_per_scan_line = (m_image_x_size * m_dest_bytes_per_pixel); 2734 2735 // Initialize two scan line buffers. 2736 m_pScan_line_0 = cast(ubyte*)alloc(m_dest_bytes_per_scan_line, true); 2737 if ((m_scan_type == JPGD_YH1V2) || (m_scan_type == JPGD_YH2V2)) 2738 m_pScan_line_1 = cast(ubyte*)alloc(m_dest_bytes_per_scan_line, true); 2739 2740 m_max_blocks_per_row = m_max_mcus_per_row * m_max_blocks_per_mcu; 2741 2742 // Should never happen 2743 if (m_max_blocks_per_row > JPGD_MAX_BLOCKS_PER_ROW) 2744 stop_decoding(JPGD_ASSERTION_ERROR); 2745 2746 // Allocate the coefficient buffer, enough for one MCU 2747 m_pMCU_coefficients = cast(jpgd_block_t*)alloc(m_max_blocks_per_mcu * 64 * jpgd_block_t.sizeof); 2748 2749 for (i = 0; i < m_max_blocks_per_mcu; i++) 2750 m_mcu_block_max_zag.ptr[i] = 64; 2751 2752 m_expanded_blocks_per_component = m_comp_h_samp.ptr[0] * m_comp_v_samp.ptr[0]; 2753 m_expanded_blocks_per_mcu = m_expanded_blocks_per_component * m_comps_in_frame; 2754 m_expanded_blocks_per_row = m_max_mcus_per_row * m_expanded_blocks_per_mcu; 2755 // Freq. domain chroma upsampling is only supported for H2V2 subsampling factor (the most common one I've seen). 2756 m_freq_domain_chroma_upsample = false; 2757 version(JPGD_SUPPORT_FREQ_DOMAIN_UPSAMPLING) { 2758 m_freq_domain_chroma_upsample = (m_expanded_blocks_per_mcu == 4*3); 2759 } 2760 2761 if (m_freq_domain_chroma_upsample) 2762 m_pSample_buf = cast(ubyte*)alloc(m_expanded_blocks_per_row * 64); 2763 else 2764 m_pSample_buf = cast(ubyte*)alloc(m_max_blocks_per_row * 64); 2765 2766 m_total_lines_left = m_image_y_size; 2767 2768 m_mcu_lines_left = 0; 2769 2770 create_look_ups(); 2771 } 2772 2773 // The coeff_buf series of methods originally stored the coefficients 2774 // into a "virtual" file which was located in EMS, XMS, or a disk file. A cache 2775 // was used to make this process more efficient. Now, we can store the entire 2776 // thing in RAM. 2777 coeff_buf* coeff_buf_open(int block_num_x, int block_num_y, int block_len_x, int block_len_y) { 2778 coeff_buf* cb = cast(coeff_buf*)alloc(coeff_buf.sizeof); 2779 2780 cb.block_num_x = block_num_x; 2781 cb.block_num_y = block_num_y; 2782 cb.block_len_x = block_len_x; 2783 cb.block_len_y = block_len_y; 2784 cb.block_size = (block_len_x * block_len_y) * cast(int)(jpgd_block_t.sizeof); 2785 cb.pData = cast(ubyte*)alloc(cb.block_size * block_num_x * block_num_y, true); 2786 return cb; 2787 } 2788 2789 jpgd_block_t* coeff_buf_getp (coeff_buf *cb, int block_x, int block_y) { 2790 assert((block_x < cb.block_num_x) && (block_y < cb.block_num_y)); 2791 return cast(jpgd_block_t*)(cb.pData + block_x * cb.block_size + block_y * (cb.block_size * cb.block_num_x)); 2792 } 2793 2794 // The following methods decode the various types of m_blocks encountered 2795 // in progressively encoded images. 2796 static void decode_block_dc_first (ref jpeg_decoder pD, int component_id, int block_x, int block_y) { 2797 int s, r; 2798 jpgd_block_t *p = pD.coeff_buf_getp(pD.m_dc_coeffs.ptr[component_id], block_x, block_y); 2799 2800 if ((s = pD.huff_decode(pD.m_pHuff_tabs.ptr[pD.m_comp_dc_tab.ptr[component_id]])) != 0) 2801 { 2802 r = pD.get_bits_no_markers(s); 2803 s = JPGD_HUFF_EXTEND(r, s); 2804 } 2805 2806 pD.m_last_dc_val.ptr[component_id] = (s += pD.m_last_dc_val.ptr[component_id]); 2807 2808 p[0] = cast(jpgd_block_t)(s << pD.m_successive_low); 2809 } 2810 2811 static void decode_block_dc_refine (ref jpeg_decoder pD, int component_id, int block_x, int block_y) { 2812 if (pD.get_bits_no_markers(1)) 2813 { 2814 jpgd_block_t *p = pD.coeff_buf_getp(pD.m_dc_coeffs.ptr[component_id], block_x, block_y); 2815 2816 p[0] |= (1 << pD.m_successive_low); 2817 } 2818 } 2819 2820 static void decode_block_ac_first (ref jpeg_decoder pD, int component_id, int block_x, int block_y) { 2821 int k, s, r; 2822 2823 if (pD.m_eob_run) 2824 { 2825 pD.m_eob_run--; 2826 return; 2827 } 2828 2829 jpgd_block_t *p = pD.coeff_buf_getp(pD.m_ac_coeffs.ptr[component_id], block_x, block_y); 2830 2831 for (k = pD.m_spectral_start; k <= pD.m_spectral_end; k++) 2832 { 2833 s = pD.huff_decode(pD.m_pHuff_tabs.ptr[pD.m_comp_ac_tab.ptr[component_id]]); 2834 2835 r = s >> 4; 2836 s &= 15; 2837 2838 if (s) 2839 { 2840 if ((k += r) > 63) 2841 pD.stop_decoding(JPGD_DECODE_ERROR); 2842 2843 r = pD.get_bits_no_markers(s); 2844 s = JPGD_HUFF_EXTEND(r, s); 2845 2846 p[g_ZAG[k]] = cast(jpgd_block_t)(s << pD.m_successive_low); 2847 } 2848 else 2849 { 2850 if (r == 15) 2851 { 2852 if ((k += 15) > 63) 2853 pD.stop_decoding(JPGD_DECODE_ERROR); 2854 } 2855 else 2856 { 2857 pD.m_eob_run = 1 << r; 2858 2859 if (r) 2860 pD.m_eob_run += pD.get_bits_no_markers(r); 2861 2862 pD.m_eob_run--; 2863 2864 break; 2865 } 2866 } 2867 } 2868 } 2869 2870 static void decode_block_ac_refine (ref jpeg_decoder pD, int component_id, int block_x, int block_y) { 2871 int s, k, r; 2872 int p1 = 1 << pD.m_successive_low; 2873 int m1 = (-1) << pD.m_successive_low; 2874 jpgd_block_t *p = pD.coeff_buf_getp(pD.m_ac_coeffs.ptr[component_id], block_x, block_y); 2875 2876 assert(pD.m_spectral_end <= 63); 2877 2878 k = pD.m_spectral_start; 2879 2880 if (pD.m_eob_run == 0) 2881 { 2882 for ( ; k <= pD.m_spectral_end; k++) 2883 { 2884 s = pD.huff_decode(pD.m_pHuff_tabs.ptr[pD.m_comp_ac_tab.ptr[component_id]]); 2885 2886 r = s >> 4; 2887 s &= 15; 2888 2889 if (s) 2890 { 2891 if (s != 1) 2892 pD.stop_decoding(JPGD_DECODE_ERROR); 2893 2894 if (pD.get_bits_no_markers(1)) 2895 s = p1; 2896 else 2897 s = m1; 2898 } 2899 else 2900 { 2901 if (r != 15) 2902 { 2903 pD.m_eob_run = 1 << r; 2904 2905 if (r) 2906 pD.m_eob_run += pD.get_bits_no_markers(r); 2907 2908 break; 2909 } 2910 } 2911 2912 do 2913 { 2914 jpgd_block_t *this_coef = p + g_ZAG[k & 63]; 2915 2916 if (*this_coef != 0) 2917 { 2918 if (pD.get_bits_no_markers(1)) 2919 { 2920 if ((*this_coef & p1) == 0) 2921 { 2922 if (*this_coef >= 0) 2923 *this_coef = cast(jpgd_block_t)(*this_coef + p1); 2924 else 2925 *this_coef = cast(jpgd_block_t)(*this_coef + m1); 2926 } 2927 } 2928 } 2929 else 2930 { 2931 if (--r < 0) 2932 break; 2933 } 2934 2935 k++; 2936 2937 } while (k <= pD.m_spectral_end); 2938 2939 if ((s) && (k < 64)) 2940 { 2941 p[g_ZAG[k]] = cast(jpgd_block_t)(s); 2942 } 2943 } 2944 } 2945 2946 if (pD.m_eob_run > 0) 2947 { 2948 for ( ; k <= pD.m_spectral_end; k++) 2949 { 2950 jpgd_block_t *this_coef = p + g_ZAG[k & 63]; // logical AND to shut up static code analysis 2951 2952 if (*this_coef != 0) 2953 { 2954 if (pD.get_bits_no_markers(1)) 2955 { 2956 if ((*this_coef & p1) == 0) 2957 { 2958 if (*this_coef >= 0) 2959 *this_coef = cast(jpgd_block_t)(*this_coef + p1); 2960 else 2961 *this_coef = cast(jpgd_block_t)(*this_coef + m1); 2962 } 2963 } 2964 } 2965 } 2966 2967 pD.m_eob_run--; 2968 } 2969 } 2970 2971 // Decode a scan in a progressively encoded image. 2972 void decode_scan (pDecode_block_func decode_block_func) { 2973 int mcu_row, mcu_col, mcu_block; 2974 int[JPGD_MAX_COMPONENTS] block_x_mcu; 2975 int[JPGD_MAX_COMPONENTS] m_block_y_mcu; 2976 2977 memset(m_block_y_mcu.ptr, 0, m_block_y_mcu.sizeof); 2978 2979 for (mcu_col = 0; mcu_col < m_mcus_per_col; mcu_col++) 2980 { 2981 int component_num, component_id; 2982 2983 memset(block_x_mcu.ptr, 0, block_x_mcu.sizeof); 2984 2985 for (mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++) 2986 { 2987 int block_x_mcu_ofs = 0, block_y_mcu_ofs = 0; 2988 2989 if ((m_restart_interval) && (m_restarts_left == 0)) 2990 process_restart(); 2991 2992 for (mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++) 2993 { 2994 component_id = m_mcu_org.ptr[mcu_block]; 2995 2996 decode_block_func(this, component_id, block_x_mcu.ptr[component_id] + block_x_mcu_ofs, m_block_y_mcu.ptr[component_id] + block_y_mcu_ofs); 2997 2998 if (m_comps_in_scan == 1) 2999 block_x_mcu.ptr[component_id]++; 3000 else 3001 { 3002 if (++block_x_mcu_ofs == m_comp_h_samp.ptr[component_id]) 3003 { 3004 block_x_mcu_ofs = 0; 3005 3006 if (++block_y_mcu_ofs == m_comp_v_samp.ptr[component_id]) 3007 { 3008 block_y_mcu_ofs = 0; 3009 block_x_mcu.ptr[component_id] += m_comp_h_samp.ptr[component_id]; 3010 } 3011 } 3012 } 3013 } 3014 3015 m_restarts_left--; 3016 } 3017 3018 if (m_comps_in_scan == 1) 3019 m_block_y_mcu.ptr[m_comp_list.ptr[0]]++; 3020 else 3021 { 3022 for (component_num = 0; component_num < m_comps_in_scan; component_num++) 3023 { 3024 component_id = m_comp_list.ptr[component_num]; 3025 m_block_y_mcu.ptr[component_id] += m_comp_v_samp.ptr[component_id]; 3026 } 3027 } 3028 } 3029 } 3030 3031 // Decode a progressively encoded image. 3032 void init_progressive () { 3033 int i; 3034 3035 if (m_comps_in_frame == 4) 3036 stop_decoding(JPGD_UNSUPPORTED_COLORSPACE); 3037 3038 // Allocate the coefficient buffers. 3039 for (i = 0; i < m_comps_in_frame; i++) 3040 { 3041 m_dc_coeffs.ptr[i] = coeff_buf_open(m_max_mcus_per_row * m_comp_h_samp.ptr[i], m_max_mcus_per_col * m_comp_v_samp.ptr[i], 1, 1); 3042 m_ac_coeffs.ptr[i] = coeff_buf_open(m_max_mcus_per_row * m_comp_h_samp.ptr[i], m_max_mcus_per_col * m_comp_v_samp.ptr[i], 8, 8); 3043 } 3044 3045 for ( ; ; ) 3046 { 3047 int dc_only_scan, refinement_scan; 3048 pDecode_block_func decode_block_func; 3049 3050 if (!init_scan()) 3051 break; 3052 3053 dc_only_scan = (m_spectral_start == 0); 3054 refinement_scan = (m_successive_high != 0); 3055 3056 if ((m_spectral_start > m_spectral_end) || (m_spectral_end > 63)) 3057 stop_decoding(JPGD_BAD_SOS_SPECTRAL); 3058 3059 if (dc_only_scan) 3060 { 3061 if (m_spectral_end) 3062 stop_decoding(JPGD_BAD_SOS_SPECTRAL); 3063 } 3064 else if (m_comps_in_scan != 1) /* AC scans can only contain one component */ 3065 stop_decoding(JPGD_BAD_SOS_SPECTRAL); 3066 3067 if ((refinement_scan) && (m_successive_low != m_successive_high - 1)) 3068 stop_decoding(JPGD_BAD_SOS_SUCCESSIVE); 3069 3070 if (dc_only_scan) 3071 { 3072 if (refinement_scan) 3073 decode_block_func = &decode_block_dc_refine; 3074 else 3075 decode_block_func = &decode_block_dc_first; 3076 } 3077 else 3078 { 3079 if (refinement_scan) 3080 decode_block_func = &decode_block_ac_refine; 3081 else 3082 decode_block_func = &decode_block_ac_first; 3083 } 3084 3085 decode_scan(decode_block_func); 3086 3087 m_bits_left = 16; 3088 get_bits(16); 3089 get_bits(16); 3090 } 3091 3092 m_comps_in_scan = m_comps_in_frame; 3093 3094 for (i = 0; i < m_comps_in_frame; i++) 3095 m_comp_list.ptr[i] = i; 3096 3097 calc_mcu_block_order(); 3098 } 3099 3100 void init_sequential () { 3101 if (!init_scan()) 3102 stop_decoding(JPGD_UNEXPECTED_MARKER); 3103 } 3104 3105 void decode_start () { 3106 init_frame(); 3107 3108 if (m_progressive_flag) 3109 init_progressive(); 3110 else 3111 init_sequential(); 3112 } 3113 3114 void decode_init (JpegStreamReadFunc rfn, void* userData) { 3115 initit(rfn, userData); 3116 locate_sof_marker(); 3117 } 3118 } 3119 3120 // ////////////////////////////////////////////////////////////////////////// // 3121 /// decompress JPEG image, what else? 3122 /// you can specify required color components in `req_comps` (3 for RGB or 4 for RGBA), or leave it as is to use image value. 3123 /// Returns pixelAspectRatio and dotsPerInchY, -1 if not available. 3124 public ubyte[] decompress_jpeg_image_from_stream(scope JpegStreamReadFunc rfn, void* userData, 3125 out int width, out int height, out int actual_comps, 3126 out float pixelAspectRatio, out float dotsPerInchY, 3127 int req_comps=-1) { 3128 3129 //actual_comps = 0; 3130 if (rfn is null) return null; 3131 if (req_comps != -1 && req_comps != 1 && req_comps != 3 && req_comps != 4) return null; 3132 3133 auto decoder = jpeg_decoder(rfn, userData); 3134 if (decoder.error_code != JPGD_SUCCESS) return null; 3135 version(jpegd_test) scope(exit) { import core.stdc.stdio : printf; printf("%u bytes read.\n", cast(uint)decoder.total_bytes_read); } 3136 3137 immutable int image_width = decoder.width; 3138 immutable int image_height = decoder.height; 3139 width = image_width; 3140 height = image_height; 3141 pixelAspectRatio = -1; 3142 dotsPerInchY = -1; 3143 actual_comps = decoder.num_components; 3144 if (req_comps < 0) req_comps = decoder.num_components; 3145 3146 if (decoder.begin_decoding() != JPGD_SUCCESS) return null; 3147 3148 immutable int dst_bpl = image_width*req_comps; 3149 3150 ubyte* pImage_data = cast(ubyte*)jpgd_malloc(dst_bpl*image_height); 3151 if (pImage_data is null) return null; 3152 auto idata = pImage_data[0..dst_bpl*image_height]; 3153 3154 for (int y = 0; y < image_height; ++y) { 3155 const(ubyte)* pScan_line; 3156 uint scan_line_len; 3157 if (decoder.decode(/*(const void**)*/cast(void**)&pScan_line, &scan_line_len) != JPGD_SUCCESS) { 3158 jpgd_free(pImage_data); 3159 return null; 3160 } 3161 3162 ubyte* pDst = pImage_data+y*dst_bpl; 3163 3164 if ((req_comps == 1 && decoder.num_components == 1) || (req_comps == 4 && decoder.num_components == 3)) { 3165 memcpy(pDst, pScan_line, dst_bpl); 3166 } else if (decoder.num_components == 1) { 3167 if (req_comps == 3) { 3168 for (int x = 0; x < image_width; ++x) { 3169 ubyte luma = pScan_line[x]; 3170 pDst[0] = luma; 3171 pDst[1] = luma; 3172 pDst[2] = luma; 3173 pDst += 3; 3174 } 3175 } else { 3176 for (int x = 0; x < image_width; ++x) { 3177 ubyte luma = pScan_line[x]; 3178 pDst[0] = luma; 3179 pDst[1] = luma; 3180 pDst[2] = luma; 3181 pDst[3] = 255; 3182 pDst += 4; 3183 } 3184 } 3185 } else if (decoder.num_components == 3) { 3186 if (req_comps == 1) { 3187 immutable int YR = 19595, YG = 38470, YB = 7471; 3188 for (int x = 0; x < image_width; ++x) { 3189 int r = pScan_line[x*4+0]; 3190 int g = pScan_line[x*4+1]; 3191 int b = pScan_line[x*4+2]; 3192 *pDst++ = cast(ubyte)((r * YR + g * YG + b * YB + 32768) >> 16); 3193 } 3194 } else { 3195 for (int x = 0; x < image_width; ++x) { 3196 pDst[0] = pScan_line[x*4+0]; 3197 pDst[1] = pScan_line[x*4+1]; 3198 pDst[2] = pScan_line[x*4+2]; 3199 pDst += 3; 3200 } 3201 } 3202 } 3203 } 3204 3205 pixelAspectRatio = decoder.m_pixelAspectRatio; 3206 dotsPerInchY = decoder.m_pixelsPerInchY; 3207 3208 return idata; 3209 }