PageRenderTime 119ms CodeModel.GetById 2ms app.highlight 105ms RepoModel.GetById 1ms app.codeStats 1ms

/decoders/image/jpeg.d

http://github.com/wilkie/djehuty
D | 1567 lines | 1002 code | 400 blank | 165 comment | 198 complexity | e4752d3267babf5e0ea4721ad2410ce7 MD5 | raw file
   1/*
   2 * jpeg.d
   3 *
   4 * This module implements the JPEG image standard.
   5 *
   6 * Author: Dave Wilkinson
   7 *
   8 */
   9
  10module decoders.image.jpeg;
  11
  12import graphics.bitmap;
  13
  14import core.string;
  15import core.stream;
  16import core.endian;
  17import core.definitions;
  18
  19import decoders.image.decoder;
  20import decoders.decoder;
  21
  22private {
  23	// Decoder States
  24	enum {
  25		JPEG_STATE_INIT_PROGRESS,
  26
  27		JPEG_STATE_READ_HEADER,
  28		JPEG_STATE_READ_CHUNK_TYPE,
  29		JPEG_STATE_READ_CHUNK_SIZE,
  30
  31		JPEG_STATE_INTERPRET_CHUNK,
  32		JPEG_STATE_SKIP_CHUNK,
  33
  34		JPEG_STATE_START_OF_IMAGE,
  35
  36		JPEG_STATE_CHUNK_SOF0,
  37		JPEG_STATE_CHUNK_SOF2,
  38		JPEG_STATE_CHUNK_APP0,
  39		JPEG_STATE_CHUNK_COM,
  40		JPEG_STATE_CHUNK_DNL,
  41		JPEG_STATE_CHUNK_DRI,
  42
  43		JPEG_STATE_CHUNK_DQT,
  44		JPEG_STATE_CHUNK_DQT_READ_TABLE,
  45
  46		JPEG_STATE_CHUNK_DHT,
  47		JPEG_STATE_CHUNK_DHT_READ_LENGTHS,
  48		JPEG_STATE_CHUNK_DHT_READ_TABLE,
  49
  50		JPEG_STATE_CHUNK_SOF_READ_COMPONENTS,
  51
  52		JPEG_STATE_CHUNK_APP0_UNKNOWN,
  53		JPEG_STATE_CHUNK_APP0_JFIF,
  54
  55		JPEG_STATE_CHUNK_SOS,
  56		JPEG_STATE_CHUNK_SOS_READ_COMPONENTS,
  57		JPEG_STATE_CHUNK_SOS_READ_SELECTOR,
  58
  59
  60		JPEG_STATE_DECODE_INIT,
  61		JPEG_STATE_DECODE_HUFFMAN_INIT,
  62		JPEG_STATE_DECODE_HUFFMAN_DC,
  63		JPEG_STATE_DECODE_HUFFMAN_DC_READ,
  64		JPEG_STATE_DECODE_HUFFMAN_AC,
  65		JPEG_STATE_DECODE_HUFFMAN_AC_READ,
  66		JPEG_STATE_DECODE_IDCT,
  67
  68		JPEG_STATE_RENDER_MCU,
  69
  70		JPEG_STATE_READ_BYTE,
  71		JPEG_STATE_READ_BYTE_FF,
  72
  73		JPEG_STATE_READ_BITS,
  74	}
  75
  76	struct HUFFMAN_TABLE {
  77		ubyte[16] lengths;
  78		ubyte[][16] data;
  79		ubyte[16] data_pos;
  80		ushort[16] minor_code;
  81		ushort[16] major_code;
  82	}
  83
  84	struct SCAN_COMPONENT_SELECTOR {
  85		ubyte Cs;
  86		ubyte DC_index;	//dc huffman table index
  87		ubyte AC_index;	//ac huffman table index
  88		ubyte C;		//component identifier
  89		ubyte H;		//horizontal sampling factor
  90		ubyte V;		//vertical sampling factor
  91		ubyte Tq;		//quantization table index
  92		ushort HxV;		//number of data sections
  93		short[] data;	//data section, allocate by (scs.H * scs.V) * 64;
  94		short lastDC;
  95	}
  96
  97	struct JPEG_RENDER_INFO {
  98		HUFFMAN_TABLE[4] HT_DC;
  99		HUFFMAN_TABLE[4] HT_AC;
 100
 101		ushort[64][4] quantization_table;
 102
 103		ubyte Ns;
 104
 105		ubyte sample_precision;
 106		ushort num_lines;
 107		ushort num_samples_per_line;
 108
 109		ushort actual_image_width;
 110		ushort actual_image_height;
 111
 112		ubyte num_image_components;
 113
 114		ubyte Hmajor; ubyte Vmajor;
 115
 116		SCAN_COMPONENT_SELECTOR * scan_components;
 117
 118		ubyte * cb_upsample_lookup;
 119		ubyte * cr_upsample_lookup;
 120
 121		uint component_counter;
 122		uint component_sample_counter;
 123
 124	}
 125
 126	align(1) struct JFIF_HEADER {
 127		ubyte version_major;
 128		ubyte version_minor;
 129		ubyte density_unit;
 130		ushort density_x;
 131		ushort density_y;
 132		ubyte thumb_w;
 133		ubyte thumb_h;
 134	}
 135
 136	align(1) struct JPEG_SOF {
 137		ubyte sample_percision;			// sample percision
 138		ushort num_lines;				// number of lines
 139		ushort num_samples_per_line; 	// number of samples per line
 140		ubyte num_image_components; 	// number of image components per frame
 141	}
 142
 143	align(1) struct JPEG_SOF_COMPONENTS {
 144		ubyte[255] component_identifier; 			// C(i)
 145		ubyte[255] sampling_factor;					// H(i), V(i) - hi 4 bits: horizontal, else: vertical
 146		ubyte[255] quantization_table_destination; 	// Tq(i)
 147
 148		ubyte[255] H;
 149		ubyte[255] V;
 150		ubyte[255] HxV;
 151	}
 152
 153	align(1) struct JPEG_SOS {
 154		ubyte num_image_components;
 155	}
 156
 157	align(1) struct JPEG_SOS_COMPONENTS {
 158		ubyte[255] scan_components;			// C(j)
 159		ubyte[255] entropy_table_selector;	// Td(j), Ta(j) - hi 4 bits: DC entropy table, else: AC
 160	}
 161
 162	align(1) struct JPEG_SOS_SELECTOR {
 163		ubyte start_spectral_selector;
 164		ubyte end_spectral_selector;
 165		ubyte successive_approximation;	// Ah, Al - hi 4 bits: high, else: low
 166	}
 167
 168	align(1) struct JFIF_EXT {
 169		ubyte ext_code;
 170	}
 171
 172    //static const ushort bit_mask[] = [1, 2, 4, 8, 16, 32, 64, 128]; //, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768};
 173    static const ushort bit_mask[] = [128, 64, 32, 16, 8, 4, 2, 1]; //, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768};
 174
 175    static const ubyte zig_zag_reference[] = [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];
 176
 177    static const float cb_b_uncode[] = [
 178        -226.816f, -225.044f, -223.272f, -221.5f, -219.728f, -217.956f, -216.184f, -214.412f, -212.64f, -210.868f, -209.096f,
 179        -207.324f, -205.552f, -203.78f, -202.008f, -200.236f, -198.464f, -196.692f, -194.92f, -193.148f, -191.376f,
 180        -189.604f, -187.832f, -186.06f, -184.288f, -182.516f, -180.744f, -178.972f, -177.2f, -175.428f, -173.656f,
 181        -171.884f, -170.112f, -168.34f, -166.568f, -164.796f, -163.024f, -161.252f, -159.48f, -157.708f, -155.936f,
 182        -154.164f, -152.392f, -150.62f, -148.848f, -147.076f, -145.304f, -143.532f, -141.76f, -139.988f, -138.216f,
 183        -136.444f, -134.672f, -132.9f, -131.128f, -129.356f, -127.584f, -125.812f, -124.04f, -122.268f, -120.496f,
 184        -118.724f, -116.952f, -115.18f, -113.408f, -111.636f, -109.864f, -108.092f, -106.32f, -104.548f, -102.776f,
 185        -101.004f, -99.232f, -97.46f, -95.688f, -93.916f, -92.144f, -90.372f, -88.6f, -86.828f, -85.056f,
 186        -83.284f, -81.512f, -79.74f, -77.968f, -76.196f, -74.424f, -72.652f, -70.88f, -69.108f, -67.336f,
 187        -65.564f, -63.792f, -62.02f, -60.248f, -58.476f, -56.704f, -54.932f, -53.16f, -51.388f, -49.616f,
 188        -47.844f, -46.072f, -44.3f, -42.528f, -40.756f, -38.984f, -37.212f, -35.44f, -33.668f, -31.896f,
 189        -30.124f, -28.352f, -26.58f, -24.808f, -23.036f, -21.264f, -19.492f, -17.72f, -15.948f, -14.176f,
 190        -12.404f, -10.632f, -8.86f, -7.088f, -5.316f, -3.544f, -1.772f, 0, 1.772f, 3.544f,
 191        5.316f, 7.088f, 8.86f, 10.632f, 12.404f, 14.176f, 15.948f, 17.72f, 19.492f, 21.264f,
 192        23.036f, 24.808f, 26.58f, 28.352f, 30.124f, 31.896f, 33.668f, 35.44f, 37.212f, 38.984f,
 193        40.756f, 42.528f, 44.3f, 46.072f, 47.844f, 49.616f, 51.388f, 53.16f, 54.932f, 56.704f,
 194        58.476f, 60.248f, 62.02f, 63.792f, 65.564f, 67.336f, 69.108f, 70.88f, 72.652f, 74.424f,
 195        76.196f, 77.968f, 79.74f, 81.512f, 83.284f, 85.056f, 86.828f, 88.6f, 90.372f, 92.144f,
 196        93.916f, 95.688f, 97.46f, 99.232f, 101.004f, 102.776f, 104.548f, 106.32f, 108.092f, 109.864f,
 197        111.636f, 113.408f, 115.18f, 116.952f, 118.724f, 120.496f, 122.268f, 124.04f, 125.812f, 127.584f,
 198        129.356f, 131.128f, 132.9f, 134.672f, 136.444f, 138.216f, 139.988f, 141.76f, 143.532f, 145.304f,
 199        147.076f, 148.848f, 150.62f, 152.392f, 154.164f, 155.936f, 157.708f, 159.48f, 161.252f, 163.024f,
 200        164.796f, 166.568f, 168.34f, 170.112f, 171.884f, 173.656f, 175.428f, 177.2f, 178.972f, 180.744f,
 201        182.516f, 184.288f, 186.06f, 187.832f, 189.604f, 191.376f, 193.148f, 194.92f, 196.692f, 198.464f,
 202        200.236f, 202.008f, 203.78f, 205.552f, 207.324f, 209.096f, 210.868f, 212.64f, 214.412f, 216.184f,
 203        217.956f, 219.728f, 221.5f, 223.272f, 225.044f
 204    ];
 205
 206    static const float cb_g_uncode[] = [
 207        44.04992f, 43.70578f, 43.36164f, 43.0175f, 42.67336f, 42.32922f, 41.98508f, 41.64094f, 41.2968f, 40.95266f, 40.60852f,
 208        40.26438f, 39.92024f, 39.5761f, 39.23196f, 38.88782f, 38.54368f, 38.19954f, 37.8554f, 37.51126f, 37.16712f,
 209        36.82298f, 36.47884f, 36.1347f, 35.79056f, 35.44642f, 35.10228f, 34.75814f, 34.414f, 34.06986f, 33.72572f,
 210        33.38158f, 33.03744f, 32.6933f, 32.34916f, 32.00502f, 31.66088f, 31.31674f, 30.9726f, 30.62846f, 30.28432f,
 211        29.94018f, 29.59604f, 29.2519f, 28.90776f, 28.56362f, 28.21948f, 27.87534f, 27.5312f, 27.18706f, 26.84292f,
 212        26.49878f, 26.15464f, 25.8105f, 25.46636f, 25.12222f, 24.77808f, 24.43394f, 24.0898f, 23.74566f, 23.40152f,
 213        23.05738f, 22.71324f, 22.3691f, 22.02496f, 21.68082f, 21.33668f, 20.99254f, 20.6484f, 20.30426f, 19.96012f,
 214        19.61598f, 19.27184f, 18.9277f, 18.58356f, 18.23942f, 17.89528f, 17.55114f, 17.207f, 16.86286f, 16.51872f,
 215        16.17458f, 15.83044f, 15.4863f, 15.14216f, 14.79802f, 14.45388f, 14.10974f, 13.7656f, 13.42146f, 13.07732f,
 216        12.73318f, 12.38904f, 12.0449f, 11.70076f, 11.35662f, 11.01248f, 10.66834f, 10.3242f, 9.98006f, 9.63592f,
 217        9.29178f, 8.94764f, 8.6035f, 8.25936f, 7.91522f, 7.57108f, 7.22694f, 6.8828f, 6.53866f, 6.19452f,
 218        5.85038f, 5.50624f, 5.1621f, 4.81796f, 4.47382f, 4.12968f, 3.78554f, 3.4414f, 3.09726f, 2.75312f,
 219        2.40898f, 2.06484f, 1.7207f, 1.37656f, 1.03242f, 0.68828f, 0.34414f, 0, -0.34414f, -0.68828f,
 220        -1.03242f, -1.37656f, -1.7207f, -2.06484f, -2.40898f, -2.75312f, -3.09726f, -3.4414f, -3.78554f, -4.12968f,
 221        -4.47382f, -4.81796f, -5.1621f, -5.50624f, -5.85038f, -6.19452f, -6.53866f, -6.8828f, -7.22694f, -7.57108f,
 222        -7.91522f, -8.25936f, -8.6035f, -8.94764f, -9.29178f, -9.63592f, -9.98006f, -10.3242f, -10.66834f, -11.01248f,
 223        -11.35662f, -11.70076f, -12.0449f, -12.38904f, -12.73318f, -13.07732f, -13.42146f, -13.7656f, -14.10974f, -14.45388f,
 224        -14.79802f, -15.14216f, -15.4863f, -15.83044f, -16.17458f, -16.51872f, -16.86286f, -17.207f, -17.55114f, -17.89528f,
 225        -18.23942f, -18.58356f, -18.9277f, -19.27184f, -19.61598f, -19.96012f, -20.30426f, -20.6484f, -20.99254f, -21.33668f,
 226        -21.68082f, -22.02496f, -22.3691f, -22.71324f, -23.05738f, -23.40152f, -23.74566f, -24.0898f, -24.43394f, -24.77808f,
 227        -25.12222f, -25.46636f, -25.8105f, -26.15464f, -26.49878f, -26.84292f, -27.18706f, -27.5312f, -27.87534f, -28.21948f,
 228        -28.56362f, -28.90776f, -29.2519f, -29.59604f, -29.94018f, -30.28432f, -30.62846f, -30.9726f, -31.31674f, -31.66088f,
 229        -32.00502f, -32.34916f, -32.6933f, -33.03744f, -33.38158f, -33.72572f, -34.06986f, -34.414f, -34.75814f, -35.10228f,
 230        -35.44642f, -35.79056f, -36.1347f, -36.47884f, -36.82298f, -37.16712f, -37.51126f, -37.8554f, -38.19954f, -38.54368f,
 231        -38.88782f, -39.23196f, -39.5761f, -39.92024f, -40.26438f, -40.60852f, -40.95266f, -41.2968f, -41.64094f, -41.98508f,
 232        -42.32922f, -42.67336f, -43.0175f, -43.36164f, -43.70578f
 233    ];
 234
 235    static const float cr_g_uncode[] = [
 236        -91.40992f, -90.69578f, -89.98164f, -89.2675f, -88.55336f, -87.83922f, -87.12508f, -86.41094f, -85.6968f, -84.98266f, -84.26852f,
 237        -83.55438f, -82.84024f, -82.1261f, -81.41196f, -80.69782f, -79.98368f, -79.26954f, -78.5554f, -77.84126f, -77.12712f,
 238        -76.41298f, -75.69884f, -74.9847f, -74.27056f, -73.55642f, -72.84228f, -72.12814f, -71.414f, -70.69986f, -69.98572f,
 239        -69.27158f, -68.55744f, -67.8433f, -67.12916f, -66.41502f, -65.70088f, -64.98674f, -64.2726f, -63.55846f, -62.84432f,
 240        -62.13018f, -61.41604f, -60.7019f, -59.98776f, -59.27362f, -58.55948f, -57.84534f, -57.1312f, -56.41706f, -55.70292f,
 241        -54.98878f, -54.27464f, -53.5605f, -52.84636f, -52.13222f, -51.41808f, -50.70394f, -49.9898f, -49.27566f, -48.56152f,
 242        -47.84738f, -47.13324f, -46.4191f, -45.70496f, -44.99082f, -44.27668f, -43.56254f, -42.8484f, -42.13426f, -41.42012f,
 243        -40.70598f, -39.99184f, -39.2777f, -38.56356f, -37.84942f, -37.13528f, -36.42114f, -35.707f, -34.99286f, -34.27872f,
 244        -33.56458f, -32.85044f, -32.1363f, -31.42216f, -30.70802f, -29.99388f, -29.27974f, -28.5656f, -27.85146f, -27.13732f,
 245        -26.42318f, -25.70904f, -24.9949f, -24.28076f, -23.56662f, -22.85248f, -22.13834f, -21.4242f, -20.71006f, -19.99592f,
 246        -19.28178f, -18.56764f, -17.8535f, -17.13936f, -16.42522f, -15.71108f, -14.99694f, -14.2828f, -13.56866f, -12.85452f,
 247        -12.14038f, -11.42624f, -10.7121f, -9.99796f, -9.28382f, -8.56968f, -7.85554f, -7.1414f, -6.42726f, -5.71312f,
 248        -4.99898f, -4.28484f, -3.5707f, -2.85656f, -2.14242f, -1.42828f, -0.71414f, 0, 0.71414f, 1.42828f,
 249        2.14242f, 2.85656f, 3.5707f, 4.28484f, 4.99898f, 5.71312f, 6.42726f, 7.1414f, 7.85554f, 8.56968f,
 250        9.28382f, 9.99796f, 10.7121f, 11.42624f, 12.14038f, 12.85452f, 13.56866f, 14.2828f, 14.99694f, 15.71108f,
 251        16.42522f, 17.13936f, 17.8535f, 18.56764f, 19.28178f, 19.99592f, 20.71006f, 21.4242f, 22.13834f, 22.85248f,
 252        23.56662f, 24.28076f, 24.9949f, 25.70904f, 26.42318f, 27.13732f, 27.85146f, 28.5656f, 29.27974f, 29.99388f,
 253        30.70802f, 31.42216f, 32.1363f, 32.85044f, 33.56458f, 34.27872f, 34.99286f, 35.707f, 36.42114f, 37.13528f,
 254        37.84942f, 38.56356f, 39.2777f, 39.99184f, 40.70598f, 41.42012f, 42.13426f, 42.8484f, 43.56254f, 44.27668f,
 255        44.99082f, 45.70496f, 46.4191f, 47.13324f, 47.84738f, 48.56152f, 49.27566f, 49.9898f, 50.70394f, 51.41808f,
 256        52.13222f, 52.84636f, 53.5605f, 54.27464f, 54.98878f, 55.70292f, 56.41706f, 57.1312f, 57.84534f, 58.55948f,
 257        59.27362f, 59.98776f, 60.7019f, 61.41604f, 62.13018f, 62.84432f, 63.55846f, 64.2726f, 64.98674f, 65.70088f,
 258        66.41502f, 67.12916f, 67.8433f, 68.55744f, 69.27158f, 69.98572f, 70.69986f, 71.414f, 72.12814f, 72.84228f,
 259        73.55642f, 74.27056f, 74.9847f, 75.69884f, 76.41298f, 77.12712f, 77.84126f, 78.5554f, 79.26954f, 79.98368f,
 260        80.69782f, 81.41196f, 82.1261f, 82.84024f, 83.55438f, 84.26852f, 84.98266f, 85.6968f, 86.41094f, 87.12508f,
 261        87.83922f, 88.55336f, 89.2675f, 89.98164f, 90.69578f
 262    ];
 263
 264    static const float cr_r_uncode[] = [
 265        -179.456f, -178.054f, -176.652f, -175.25f, -173.848f, -172.446f, -171.044f, -169.642f, -168.24f, -166.838f, -165.436f,
 266        -164.034f, -162.632f, -161.23f, -159.828f, -158.426f, -157.024f, -155.622f, -154.22f, -152.818f, -151.416f,
 267        -150.014f, -148.612f, -147.21f, -145.808f, -144.406f, -143.004f, -141.602f, -140.2f, -138.798f, -137.396f,
 268        -135.994f, -134.592f, -133.19f, -131.788f, -130.386f, -128.984f, -127.582f, -126.18f, -124.778f, -123.376f,
 269        -121.974f, -120.572f, -119.17f, -117.768f, -116.366f, -114.964f, -113.562f, -112.16f, -110.758f, -109.356f,
 270        -107.954f, -106.552f, -105.15f, -103.748f, -102.346f, -100.944f, -99.542f, -98.14f, -96.738f, -95.336f,
 271        -93.934f, -92.532f, -91.13f, -89.728f, -88.326f, -86.924f, -85.522f, -84.12f, -82.718f, -81.316f,
 272        -79.914f, -78.512f, -77.11f, -75.708f, -74.306f, -72.904f, -71.502f, -70.1f, -68.698f, -67.296f,
 273        -65.894f, -64.492f, -63.09f, -61.688f, -60.286f, -58.884f, -57.482f, -56.08f, -54.678f, -53.276f,
 274        -51.874f, -50.472f, -49.07f, -47.668f, -46.266f, -44.864f, -43.462f, -42.06f, -40.658f, -39.256f,
 275        -37.854f, -36.452f, -35.05f, -33.648f, -32.246f, -30.844f, -29.442f, -28.04f, -26.638f, -25.236f,
 276        -23.834f, -22.432f, -21.03f, -19.628f, -18.226f, -16.824f, -15.422f, -14.02f, -12.618f, -11.216f,
 277        -9.814f, -8.412f, -7.01f, -5.608f, -4.206f, -2.804f, -1.402f, 0, 1.402f, 2.804f,
 278        4.206f, 5.608f, 7.01f, 8.412f, 9.814f, 11.216f, 12.618f, 14.02f, 15.422f, 16.824f,
 279        18.226f, 19.628f, 21.03f, 22.432f, 23.834f, 25.236f, 26.638f, 28.04f, 29.442f, 30.844f,
 280        32.246f, 33.648f, 35.05f, 36.452f, 37.854f, 39.256f, 40.658f, 42.06f, 43.462f, 44.864f,
 281        46.266f, 47.668f, 49.07f, 50.472f, 51.874f, 53.276f, 54.678f, 56.08f, 57.482f, 58.884f,
 282        60.286f, 61.688f, 63.09f, 64.492f, 65.894f, 67.296f, 68.698f, 70.1f, 71.502f, 72.904f,
 283        74.306f, 75.708f, 77.11f, 78.512f, 79.914f, 81.316f, 82.718f, 84.12f, 85.522f, 86.924f,
 284        88.326f, 89.728f, 91.13f, 92.532f, 93.934f, 95.336f, 96.738f, 98.14f, 99.542f, 100.944f,
 285        102.346f, 103.748f, 105.15f, 106.552f, 107.954f, 109.356f, 110.758f, 112.16f, 113.562f, 114.964f,
 286        116.366f, 117.768f, 119.17f, 120.572f, 121.974f, 123.376f, 124.778f, 126.18f, 127.582f, 128.984f,
 287        130.386f, 131.788f, 133.19f, 134.592f, 135.994f, 137.396f, 138.798f, 140.2f, 141.602f, 143.004f,
 288        144.406f, 145.808f, 147.21f, 148.612f, 150.014f, 151.416f, 152.818f, 154.22f, 155.622f, 157.024f,
 289        158.426f, 159.828f, 161.23f, 162.632f, 164.034f, 165.436f, 166.838f, 168.24f, 169.642f, 171.044f,
 290        172.446f, 173.848f, 175.25f, 176.652f, 178.054f
 291    ];
 292
 293  }
 294
 295// Section: Codecs/Image
 296
 297// Description: The JPEG Codec
 298
 299class JPEGDecoder : ImageDecoder {
 300
 301	override string name() {
 302		return "Joint Picture Experts Group";
 303	}
 304
 305	StreamData decode(Stream stream, ref Bitmap view) {
 306		ImageFrameDescription imageDesc;
 307		bool hasMultipleFrames;
 308
 309		hasMultipleFrames = false;
 310
 311		ushort header;
 312		ubyte byteCheck;
 313
 314		for (;;) {
 315			switch(decoderState) {
 316				case JPEG_STATE_READ_BYTE:
 317
 318					//writefln("jpeg - decode - read byte");
 319
 320					if (!stream.read(cur_byte)) {
 321						return StreamData.Required;
 322					}
 323
 324					//cur_byte = file[file_idx];
 325					//file_idx++;
 326
 327					cur_bit_pos = 0;
 328
 329					// check for a FF block
 330					// if this is a 0xFF and the next block is a 0x00,
 331					// then we use this block, but skip the next byte
 332					if (cur_byte != 0xFF) {
 333						decoderState = decoderNextState;
 334						continue;
 335					}
 336
 337					/* follow through */
 338
 339				case JPEG_STATE_READ_BYTE_FF:
 340
 341					ubyte test_byte;
 342
 343					if (!stream.read(test_byte)) {
 344						return StreamData.Required;
 345					}
 346
 347					//test_byte = file[file_idx];
 348					//file_idx++;
 349
 350					// if this is not a 0x00, then check for the block type
 351					// else, this just effectively skips the 0x00
 352
 353					if (test_byte == 0xD9) {
 354						// EOI (End Of Image)
 355						return StreamData.Complete;
 356					}
 357
 358					decoderState = decoderNextState;
 359
 360					continue;
 361
 362
 363				// state to read a certain amount of bits (bits_to_read)
 364				// and places them in bits_read
 365				case JPEG_STATE_READ_BITS:
 366
 367					// cur_bit_pos tells us how many bits remain in cur_byte
 368					// read what we can until aligned, and then read a byte
 369
 370					for (; cur_bit_pos < 8 && bits_to_read > 0; cur_bit_pos++, bits_to_read--) {
 371						if (first_bit == 0) {
 372							if (cur_byte & bit_mask[cur_bit_pos]) {
 373								bits_read = 0;
 374								first_bit = 0x11;
 375							}
 376							else {
 377								bits_read = 0xFFFF;
 378								first_bit = 0x10;
 379							}
 380						}
 381
 382						bits_read <<= 1;
 383
 384						if (cur_byte & bit_mask[cur_bit_pos]) {
 385							bits_read |= 1;
 386						}
 387					}
 388
 389					if (cur_bit_pos == 8) {
 390						decoderState = JPEG_STATE_READ_BYTE;
 391						decoderNextState = JPEG_STATE_READ_BITS;
 392						continue;
 393					}
 394
 395					if (bits_to_read == 0) {
 396						decoderState = decoderNextSubState;
 397
 398						// is it a negative?
 399						if (first_bit == 0x10) {
 400							bits_read += 1; //-bits_read;
 401						}
 402					}
 403
 404					continue;
 405
 406				case JPEG_STATE_INIT_PROGRESS:
 407
 408					decoderState = JPEG_STATE_READ_HEADER;
 409
 410					/* fall through */
 411
 412				case JPEG_STATE_READ_HEADER:
 413
 414					if (!stream.read(header)) {
 415						return StreamData.Required;
 416					}
 417
 418					if (header == FromBigEndian16(0xFFD8)) {
 419						// SOI (Start of Image)
 420
 421						decoderState = JPEG_STATE_READ_CHUNK_TYPE;
 422					}
 423					else {
 424						//header not found
 425						return StreamData.Invalid;
 426					}
 427
 428					/* follow through */
 429
 430				case JPEG_STATE_READ_CHUNK_TYPE:
 431					//writeln("jpeg - reading chunk type");
 432
 433					// get the the block type
 434					if (!stream.read(chunkType)) {
 435						return StreamData.Required;
 436					}
 437
 438					chunkType = FromBigEndian16(chunkType);
 439
 440					//grabbing info from block headers \ initing huffman tables
 441
 442					//determine the block size
 443					decoderState = JPEG_STATE_READ_CHUNK_SIZE;
 444
 445					/* follow through */
 446
 447				case JPEG_STATE_READ_CHUNK_SIZE:
 448
 449					// get chunk size
 450
 451					if (!stream.read(chunkLength)) {
 452						return StreamData.Required;
 453					}
 454
 455					chunkLength = FromBigEndian16(chunkLength);
 456					chunkLength -= 2; // supplement for the length identifier (short)
 457
 458					// interpret chunk type
 459					decoderState = JPEG_STATE_INTERPRET_CHUNK;
 460
 461					/* follow through */
 462
 463				case JPEG_STATE_INTERPRET_CHUNK:
 464					switch(chunkType) {
 465						case 0xFFC0: // SOF0	(start of frame 0 - Baseline DCT)
 466							decoderState = JPEG_STATE_CHUNK_SOF0;
 467							break;
 468						case 0xFFC2: // SOF2	(start of frame 2 - Progressive DCT)
 469							decoderState = JPEG_STATE_CHUNK_SOF2;
 470							break;
 471						case 0xFFC4: // DHT (define huffman tables)
 472							decoderState = JPEG_STATE_CHUNK_DHT;
 473							break;
 474						case 0xFFCC: // DAC (define arithmetic coding conditionings)
 475							break;
 476						case 0xFFE0: // APP0	(signifies the JFIF spec is being utilized
 477							decoderState = JPEG_STATE_CHUNK_APP0;
 478							break;
 479						case 0xFFFE: // COM	(comment)
 480							decoderState = JPEG_STATE_CHUNK_COM;
 481							break;
 482						case 0xFFD8: // SOI (start of image)
 483							break;
 484						case 0xFFD9: // EOI (end of image)
 485							break;
 486						case 0xFFDA: // SOS (start of scan)
 487							decoderState = JPEG_STATE_CHUNK_SOS;
 488							break;
 489						case 0xFFDB: // DQT	(define quantization table)
 490							decoderState = JPEG_STATE_CHUNK_DQT;
 491							break;
 492						case 0xFFDC: // DNL (define number of lines)
 493							decoderState = JPEG_STATE_CHUNK_DNL;
 494							break;
 495						case 0xFFDD: // DRI	(define restart interval)
 496							decoderState = JPEG_STATE_CHUNK_DRI;
 497							break;
 498						case 0xFFDE: // DHP (define hierarchical progression)
 499							break;
 500						case 0xFFDF: // EXP (expand reference components)
 501							break;
 502						default:
 503							// just ignore unknown blocks
 504							// and pass over the section length
 505							if (!stream.skip(chunkLength))
 506							{
 507								return StreamData.Required;
 508							}
 509							decoderState = JPEG_STATE_READ_CHUNK_TYPE;
 510							break;
 511					}
 512
 513					continue;
 514
 515				case JPEG_STATE_CHUNK_COM:
 516				case JPEG_STATE_SKIP_CHUNK:
 517
 518					if (!stream.skip(chunkLength)) {
 519						return StreamData.Required;
 520					}
 521					decoderState = JPEG_STATE_READ_CHUNK_TYPE;
 522
 523					continue;
 524
 525				// SOF0 - start of frame 0
 526				case JPEG_STATE_CHUNK_SOF0:
 527
 528					// get information about the frame (dimensions)
 529					if (!stream.read(&sof, sof.sizeof)) {
 530						return StreamData.Required;
 531					}
 532
 533					// enforce endian
 534					sof.num_lines = FromBigEndian16(sof.num_lines);
 535					sof.num_samples_per_line = FromBigEndian16(sof.num_samples_per_line);
 536
 537					decoderState = JPEG_STATE_CHUNK_SOF_READ_COMPONENTS;
 538
 539					/* follow through */
 540
 541				case JPEG_STATE_CHUNK_SOF_READ_COMPONENTS:
 542
 543					// read the image components
 544					if (stream.remaining < (sof.num_image_components * 3)) {
 545						return StreamData.Required;
 546					}
 547
 548					sof_comp = new SCAN_COMPONENT_SELECTOR[3]; //sof.num_image_components];
 549
 550					ubyte[] bytesRead = new ubyte[sof.num_image_components*3];
 551
 552					stream.read(bytesRead.ptr, bytesRead.length);
 553
 554					for (int n=0, a=0; a<sof.num_image_components; a++) {
 555						sof_comp[a].C = bytesRead[n];
 556						n++;
 557
 558						sof_comp[a].H = cast(ubyte)((bytesRead[n] & 0xF0) >> 4);
 559						sof_comp[a].V = cast(ubyte)(bytesRead[n] & 0xF);
 560						n++;
 561
 562						sof_comp[a].HxV = cast(ushort)(sof_comp[a].H * sof_comp[a].V);
 563
 564						if (Hmajor < sof_comp[a].H) { Hmajor = sof_comp[a].H; }
 565						if (Vmajor < sof_comp[a].V) { Vmajor = sof_comp[a].V; }
 566
 567						//allocate memory for the MCU data
 568						sof_comp[a].data = new short[sof_comp[a].HxV * 64];
 569
 570						sof_comp[a].Tq = bytesRead[n];
 571						n++;
 572
 573						sof_comp[a].lastDC = 0;
 574					}
 575
 576					if (sof.num_image_components == 1) {
 577						// monochrome
 578						sof_comp[1].C = 2;
 579						sof_comp[1].data = new short[64];
 580
 581						sof_comp[2].C = 3;
 582						sof_comp[2].data = new short[64];
 583					}
 584
 585					//allocate memory for the image
 586
 587					if (sof.num_samples_per_line % (Hmajor * 8) == 0) {
 588						actual_image_width = sof.num_samples_per_line;
 589					}
 590					else {
 591						actual_image_width = sof.num_samples_per_line + ((Hmajor * 8)-(sof.num_samples_per_line % (Hmajor * 8)));
 592					}
 593
 594					if (sof.num_lines % (Vmajor * 8) == 0) {
 595						actual_image_height = sof.num_lines;
 596					}
 597					else {
 598						actual_image_height = sof.num_lines + ((Vmajor * 8)-(sof.num_lines % (Vmajor * 8)));
 599					}
 600
 601					block_width = actual_image_width / (Hmajor * 8);
 602					block_height = actual_image_height / (Vmajor * 8);
 603
 604					imgylinemovement = sof.num_samples_per_line * 4;
 605					imgylinemovement_block = imgylinemovement * 8;
 606
 607					imgxlinemovement_block_start = 32 * Hmajor;
 608					imgylinemovement_block_start = imgylinemovement_block * Vmajor;
 609
 610					view.create(sof.num_samples_per_line, sof.num_lines);
 611					//view.CreateDIB(actual_image_width, actual_image_height);
 612
 613					decoderState = JPEG_STATE_READ_CHUNK_TYPE;
 614					continue;
 615
 616				// SOF2 - start of frame 2
 617				case JPEG_STATE_CHUNK_SOF2:
 618					if (!stream.skip(chunkLength)) {
 619						return StreamData.Required;
 620					}
 621					decoderState = JPEG_STATE_READ_CHUNK_TYPE;
 622					continue;
 623
 624				// APP0 - JFIF Specifications
 625				case JPEG_STATE_CHUNK_APP0:
 626					// Check for the signature of the APP0 segment
 627					char[5] signature;
 628
 629					if (!stream.read(signature.ptr, signature.length)) {
 630						return StreamData.Required;
 631					}
 632
 633					switch (signature) {
 634						case "JFIF\0":
 635							decoderState = JPEG_STATE_CHUNK_APP0_JFIF;
 636							break;
 637
 638						case "JFXX\0":
 639							break;
 640
 641						default:
 642							decoderState = JPEG_STATE_CHUNK_APP0_UNKNOWN;
 643							break;
 644					}
 645
 646					continue;
 647
 648				case JPEG_STATE_CHUNK_APP0_JFIF:
 649
 650					// skip the unknown app extension
 651					if (!stream.read(&jfif, jfif.sizeof)) {
 652						return StreamData.Required;
 653					}
 654
 655					jfif.density_x = FromBigEndian16(jfif.density_x);
 656					jfif.density_y = FromBigEndian16(jfif.density_y);
 657
 658					decoderState = JPEG_STATE_READ_CHUNK_TYPE;
 659					continue;
 660
 661				case JPEG_STATE_CHUNK_APP0_UNKNOWN:
 662					// skip the unknown app extension
 663					if (!stream.skip(chunkLength - 5)) {
 664						return StreamData.Required;
 665					}
 666
 667					decoderState = JPEG_STATE_READ_CHUNK_TYPE;
 668					continue;
 669
 670
 671
 672
 673
 674
 675				// DHT - define huffman tables
 676				case JPEG_STATE_CHUNK_DHT:
 677					ubyte table_id;
 678					if (!stream.read(table_id)) {
 679						return StreamData.Required;
 680					}
 681
 682					//find what table it should go into
 683					if (((table_id & 0x10) >> 4) == 0) {
 684						//DC TABLE
 685						cur_ht = &HT_DC[table_id & 0x03];
 686					}
 687					else {
 688						//AC TABLE
 689						cur_ht = &HT_AC[table_id & 0x03];
 690					}
 691
 692					decoderState = JPEG_STATE_CHUNK_DHT_READ_LENGTHS;
 693
 694					/* follow through */
 695
 696				case JPEG_STATE_CHUNK_DHT_READ_LENGTHS:
 697
 698					chunkLength -= 17;
 699
 700					if (!stream.read(cur_ht.lengths.ptr, 16)) {
 701						return StreamData.Required;
 702					}
 703
 704					//load the lengths into the specified table
 705					for (int a=0; a<16; a++) {
 706						int size = cur_ht.lengths[a];
 707						cur_ht.data[a] = new ubyte[size];
 708						cur_ht.data_pos[a] = 0;
 709					}
 710
 711					decoderState = JPEG_STATE_CHUNK_DHT_READ_TABLE;
 712
 713					//create the table
 714					int o=0;
 715					int n=0;
 716
 717					bytesToRead = 0;
 718
 719					for (int a=0; a<chunkLength; a++) {
 720						while (n == cur_ht.lengths[o]) {
 721							o++;
 722							n=0;
 723
 724							if (o == 16) { break; }
 725						}
 726						if (o==16) { break;	}
 727
 728						bytesToRead++;
 729						n++;
 730					}
 731
 732					/* follow through */
 733
 734				case JPEG_STATE_CHUNK_DHT_READ_TABLE:
 735
 736					ubyte[] bytesRead = new ubyte[bytesToRead];
 737
 738					if (!stream.read(bytesRead.ptr, bytesToRead)) {
 739						return StreamData.Required;
 740					}
 741
 742					//create the table
 743					int o=0;
 744					int n=0;
 745					int q=0;
 746
 747					for (int a=0; a<chunkLength; a++) {
 748						while (n == cur_ht.lengths[o]) {
 749							o++;
 750							n=0;
 751
 752							if (o == 16) { break; }
 753						}
 754						if (o==16) { break;	}
 755
 756						cur_ht.data[o][n] = bytesRead[q];
 757						q++;
 758						n++;
 759					}
 760
 761					//aquire minor and major codes
 762					o=0;
 763					for (int a=0; a<16; a++) {
 764						cur_ht.minor_code[a] = cast(ushort)(o);
 765						o += cur_ht.lengths[a];
 766						cur_ht.major_code[a] = cast(ushort)(o-1);
 767						o = o << 1;
 768						if (cur_ht.lengths[a] == 0) {
 769							cur_ht.minor_code[a] = 0xFFFF;
 770							cur_ht.major_code[a] = 0x0000;
 771						}
 772					}
 773
 774					decoderState = JPEG_STATE_READ_CHUNK_TYPE;
 775					continue;
 776
 777				// DQT - define quantization tables
 778				case JPEG_STATE_CHUNK_DQT:
 779
 780					chunkLength -= 65;	//supplement for the length identifier and the 1 byte for table id
 781
 782					ubyte quantization_type;
 783
 784					if (!stream.read(quantization_type)) {
 785						return StreamData.Required;
 786					}
 787
 788					//get Pq - which is the precision... 0 for 8 bit values and 1 for 16 bit values
 789					quantization_precision = ((quantization_type & 0x10) >> 4);
 790
 791					if (quantization_precision==1) { chunkLength -= 64; }
 792					//chunkLength should be 0 now
 793
 794					//get Tq - the destination index of the table
 795					quantization_destination = (quantization_type & 0x03);
 796
 797					decoderState = JPEG_STATE_CHUNK_DQT_READ_TABLE;
 798
 799					/* follow through */
 800
 801				case JPEG_STATE_CHUNK_DQT_READ_TABLE:
 802
 803					if (quantization_precision==0) {
 804						ubyte[64] bytesRead;
 805
 806						if (!stream.read(bytesRead.ptr, 64)) {
 807							return StreamData.Required;
 808						}
 809
 810						for (int n = 0; n < 64; n++) {
 811							quantization_table[quantization_destination][n] = bytesRead[n];
 812						}
 813					}
 814					else {
 815						ushort[64] bytesRead;
 816
 817						if (!stream.read(bytesRead.ptr, 128)) {
 818							return StreamData.Required;
 819						}
 820
 821						for (int n = 0; n < 64; n++) {
 822							quantization_table[quantization_destination][n] = FromBigEndian16(bytesRead[n]);
 823						}
 824					}
 825
 826					decoderState = JPEG_STATE_READ_CHUNK_TYPE;
 827					continue;
 828
 829				// SOS - start of scan
 830				case JPEG_STATE_CHUNK_SOS:
 831
 832					// read the number of image components in the scan
 833					// (a subset of the frame image components)
 834					if (!stream.read(&sos, sos.sizeof)) {
 835						return StreamData.Required;
 836					}
 837
 838					decoderState = JPEG_STATE_CHUNK_SOS_READ_COMPONENTS;
 839
 840					/* follow through */
 841
 842				case JPEG_STATE_CHUNK_SOS_READ_COMPONENTS:
 843
 844					if (stream.remaining < (sos.num_image_components * 2)) {
 845						return StreamData.Required;
 846					}
 847
 848					ubyte[] bytesRead = new ubyte[sof.num_image_components*2];
 849
 850					stream.read(bytesRead.ptr, bytesRead.length);
 851
 852					//get the number of source components
 853										//jpeg_vars->Ns = in_bytes[file_counter];
 854					/*
 855					if (jpeg_vars->Ns < 1 || jpeg_vars->Ns > 4) {
 856						break;
 857					}
 858
 859					if (jpeg_vars->scan_components != NULL) {
 860						if (jpeg_vars->num_image_components != jpeg_vars->Ns)
 861						{ delete jpeg_vars->scan_components; jpeg_vars->scan_components = new SCAN_COMPONENT_SELECTOR[jpeg_vars->Ns];}
 862					}
 863					else {
 864						jpeg_vars->scan_components = new SCAN_COMPONENT_SELECTOR[jpeg_vars->Ns];
 865					}*/
 866
 867					//get scan component selectors
 868					int n = 0;
 869					for (int a = 0; a < sos.num_image_components; a++) {
 870						sof_comp[a].Cs = bytesRead[n];
 871						n++;
 872
 873						sof_comp[a].DC_index = cast(ubyte)((bytesRead[n] & 0xF0) >> 4);
 874						sof_comp[a].AC_index = cast(ubyte)((bytesRead[n] & 0x0F));
 875						n++;
 876
 877						sof_comp[a].lastDC = 0;
 878					}
 879
 880					decoderState = JPEG_STATE_CHUNK_SOS_READ_SELECTOR;
 881
 882					/* follow through */
 883
 884				case JPEG_STATE_CHUNK_SOS_READ_SELECTOR:
 885					if (!stream.read(&sos_sel, sos_sel.sizeof)) {
 886						return StreamData.Required;
 887					}
 888
 889					decoderState = JPEG_STATE_DECODE_INIT;
 890
 891					/* follow through */
 892
 893				case JPEG_STATE_DECODE_INIT:
 894
 895					// decode init
 896
 897					cb_upsample_lookup = new ubyte[64 * Hmajor * Vmajor];
 898					cr_upsample_lookup = new ubyte[64 * Hmajor * Vmajor];
 899
 900					for (int a=0; a<3;a++) {
 901						sof_comp[a].lastDC = 0;
 902
 903						int d0,d1,d2,d3;
 904
 905						//create sampling lookup tables
 906						if (sof_comp[a].C == 1) {
 907							//Y component
 908						}
 909						else if (sof_comp[a].C == 2) {
 910							//ch
 911
 912							d0 = 0;
 913							d2 = (8*Hmajor);
 914							for (int n=0; n<Hmajor; n++) {
 915								for (int q=0; q<Vmajor; q++) {
 916									//starting coords for the block
 917									d1 = (q*8) + (n*64*Hmajor);
 918
 919									//for every 8x8 block in the MCU
 920									for (int o=0; o<8;o++) {
 921										d3 = d1;
 922										for (int p=0; p<8; p++) {
 923											cb_upsample_lookup[d0] = cast(ubyte)(cast(int)(d3 / (d2 * Vmajor) * 8) + cast(int)((d3 % d2)/Vmajor));
 924											//printf("cb %d, %d\n", cb_upsample_lookup[d0], d0);
 925											d3++;
 926											d0++;
 927										}
 928
 929										d1+=d2;
 930									}
 931								}
 932							}
 933						}
 934						else if (sof_comp[a].C == 3) {
 935							//cr
 936							d0 = 0;
 937							d2 = (8*Hmajor);
 938							for (int n=0; n<Hmajor; n++) {
 939								for (int q=0; q<Vmajor; q++) {
 940									//starting coords for the block
 941									d1 = (q*8) + (n*64*Hmajor);
 942
 943									//for every 8x8 block in the MCU
 944									for (int o=0; o<8;o++) {
 945										d3 = d1;
 946										for (int p=0; p<8; p++) {
 947											cr_upsample_lookup[d0] = cast(ubyte)(cast(int)(d3 / (d2 * Vmajor) * 8) + cast(int)((d3 % d2)/Vmajor));
 948											//printf("cr %d, %d\n", cr_upsample_lookup[d0], d0);
 949											d3++;
 950											d0++;
 951										}
 952
 953										d1+=d2;
 954									}
 955								}
 956							}
 957						}
 958					}
 959
 960					cur_bit_pos=7;
 961
 962					component_counter = 0;
 963					component_sample_counter = 0;
 964
 965					decoderState = JPEG_STATE_READ_BYTE;
 966					decoderNextState = JPEG_STATE_DECODE_HUFFMAN_INIT;
 967
 968					continue;
 969
 970				case JPEG_STATE_DECODE_HUFFMAN_INIT:
 971
 972					data_start_pos = 64 * component_sample_counter;
 973
 974					cur_ht = &HT_DC[sof_comp[component_counter].DC_index];
 975
 976					huffman_code = 0;
 977					huffman_bits = 0;
 978
 979					decoderState = JPEG_STATE_DECODE_HUFFMAN_DC;
 980
 981					/* follow through */
 982
 983				case JPEG_STATE_DECODE_HUFFMAN_DC:
 984
 985					// Get DC Component
 986
 987					if (huffman_bits == 16) {
 988						decoderState = JPEG_STATE_DECODE_HUFFMAN_DC_READ;
 989
 990						huffman_code = 0;
 991						huffman_bits = 0;
 992					}
 993					else {
 994						if (cur_bit_pos == 8) {
 995							decoderNextState = JPEG_STATE_DECODE_HUFFMAN_DC;
 996							decoderState = JPEG_STATE_READ_BYTE;
 997							continue;
 998						}
 999
1000						huffman_code <<= 1;
1001						if (cur_byte & bit_mask[cur_bit_pos]) {
1002							huffman_code |= 1;
1003						}
1004
1005						cur_bit_pos++;
1006
1007						if (huffman_code >= cur_ht.minor_code[huffman_bits]  && huffman_code <= cur_ht.major_code[huffman_bits]) {
1008
1009							//valid code
1010
1011							huffman_code -= cur_ht.minor_code[huffman_bits]; //get its position within that range of length!
1012							huffman_code = cur_ht.data[huffman_bits][huffman_code];
1013
1014							//huffman_code == the # of bits following the code to read in
1015							if (huffman_code == 0) {
1016								sof_comp[component_counter].data[data_start_pos] = sof_comp[component_counter].lastDC;
1017								sof_comp[component_counter].data[data_start_pos] *= quantization_table[sof_comp[component_counter].Tq][0];
1018
1019								decoderState = JPEG_STATE_DECODE_HUFFMAN_AC;
1020
1021								// init AC huffman table
1022								cur_ht = &HT_AC[sof_comp[component_counter].AC_index];
1023
1024								cur_ac = 1;
1025							}
1026							else {
1027								bits_read = 0;
1028								bits_to_read = huffman_code;
1029								first_bit = 0;
1030
1031								decoderNextSubState = JPEG_STATE_DECODE_HUFFMAN_DC_READ;
1032								decoderState = JPEG_STATE_READ_BITS;
1033							}
1034
1035							huffman_code = 0;
1036							huffman_bits = 0;
1037						}
1038						else {
1039							huffman_bits++;
1040						}
1041
1042						continue;
1043					}
1044
1045				case JPEG_STATE_DECODE_HUFFMAN_DC_READ:
1046
1047					// read_bits state has stored the read code into bits_read
1048
1049					int d0 = cast(short)bits_read;
1050
1051					//huffman_code is actually component_counter value of the dc coefficent
1052					d0 += sof_comp[component_counter].lastDC;
1053					sof_comp[component_counter].data[data_start_pos] = cast(short)d0;
1054					sof_comp[component_counter].lastDC = sof_comp[component_counter].data[data_start_pos];
1055					d0 *= quantization_table[sof_comp[component_counter].Tq][0];
1056					sof_comp[component_counter].data[data_start_pos] = cast(short)d0;
1057
1058					// init AC huffman table
1059					cur_ht = &HT_AC[sof_comp[component_counter].AC_index];
1060
1061					cur_ac = 1;
1062
1063					huffman_code = 0;
1064					huffman_bits = 0;
1065
1066					decoderState = JPEG_STATE_DECODE_HUFFMAN_AC;
1067
1068					/* follow through */
1069
1070				case JPEG_STATE_DECODE_HUFFMAN_AC:
1071
1072					// Get AC Components
1073					if (cur_ac >= 64) {
1074						// HUFFMAN CODING END
1075						decoderState = JPEG_STATE_DECODE_IDCT;
1076						huffman_code = 0;
1077						huffman_bits = 0;
1078						continue;
1079					}
1080
1081					//from the next bits in the stream...find the first valid huffman code
1082
1083					if (huffman_bits == 16) {
1084						decoderState = JPEG_STATE_DECODE_HUFFMAN_AC_READ;
1085
1086						huffman_code = 0;
1087						huffman_bits = 0;
1088					}
1089					else {
1090						if (cur_bit_pos == 8) {
1091							decoderNextState = JPEG_STATE_DECODE_HUFFMAN_AC;
1092							decoderState = JPEG_STATE_READ_BYTE;
1093							continue;
1094						}
1095
1096						huffman_code <<= 1;
1097						if (cur_byte & bit_mask[cur_bit_pos]) {
1098							huffman_code |= 1;
1099						}
1100
1101						cur_bit_pos++;
1102
1103						if (huffman_code >= cur_ht.minor_code[huffman_bits]  && huffman_code <= cur_ht.major_code[huffman_bits]) {
1104
1105							//valid code
1106
1107							huffman_code -= cur_ht.minor_code[huffman_bits]; //get its position within that range of length!
1108							huffman_code = cur_ht.data[huffman_bits][huffman_code];
1109
1110							//code: (o, q);
1111							int q=huffman_code & 0xF;	//bit_count
1112							int o=huffman_code >> 4;	//zero_count
1113
1114							if (q == 0) {
1115								if (o == 0) {
1116									//code: (0, 0)
1117									//end of data
1118									//the rest are zeroes
1119									o = 64;
1120
1121									while (cur_ac!=o) {
1122										sof_comp[component_counter].data[data_start_pos+zig_zag_reference[cur_ac]] = 0;
1123										cur_ac++;
1124									}
1125								}
1126								else if (o==0xF) {
1127									// code: (15, 0)
1128									//next 16 spaces of data are zeroes!
1129									if (cur_ac+16 > 64) {
1130										o = 64;
1131									}
1132									else {
1133										o = cur_ac+16;
1134									}
1135
1136									while (cur_ac!=o) {
1137										sof_comp[component_counter].data[data_start_pos+zig_zag_reference[cur_ac]] = 0;
1138										cur_ac++;
1139									}
1140								}
1141							}
1142							else {
1143								//set zeroes in all the spaces marked in zero_count
1144								if (cur_ac+o > 64) {
1145									o = 64;
1146								}
1147								else {
1148									o = cur_ac+o;
1149								}
1150
1151								//set the items from p to o
1152								while (cur_ac!=o) {
1153									sof_comp[component_counter].data[data_start_pos+zig_zag_reference[cur_ac]] = 0;
1154									cur_ac++;
1155								}
1156
1157								// grab the next 'q' bits from the stream
1158								bits_read = 0;
1159								bits_to_read = q;
1160								first_bit = 0;
1161
1162								decoderNextSubState = JPEG_STATE_DECODE_HUFFMAN_AC_READ;
1163								decoderState = JPEG_STATE_READ_BITS;
1164							}
1165
1166							huffman_code = 0;
1167							huffman_bits = 0;
1168						}
1169						else {
1170							huffman_bits++;
1171						}
1172					}
1173
1174					continue;
1175
1176				case JPEG_STATE_DECODE_HUFFMAN_AC_READ:
1177
1178					//bits_read is actually the value of the data
1179
1180					if (cur_ac < 64) {
1181						sof_comp[component_counter].data[data_start_pos+zig_zag_reference[cur_ac]] = cast(short)(cast(short)bits_read * quantization_table[sof_comp[component_counter].Tq][cur_ac]);
1182						cur_ac++;
1183					}
1184
1185					decoderState = JPEG_STATE_DECODE_HUFFMAN_AC;
1186					huffman_code = 0;
1187					huffman_bits = 0;
1188
1189					continue;
1190
1191				case JPEG_STATE_DECODE_IDCT:
1192					// integer, fixed point implementation of IDCT
1193
1194					//at this point we should have component_counter 8 x 8 block
1195
1196					//IDCT
1197
1198					short* dataRef = &sof_comp[component_counter].data[data_start_pos];
1199
1200					int d0,d1,d2,d3,d4,d5,d6,d7,tmp;
1201
1202					for (int o=0; o<8; o++) {
1203						d4 = dataRef[7]; d5 = dataRef[5]; d6 = dataRef[3]; d7 = dataRef[1];
1204
1205						d2 = d4 + d6; d3 = d5 + d7;
1206
1207						d1 = (d2 + d3) * 77062; d2 *= -128553; d3 *= -25571; d2 += d1; d3 += d1;
1208
1209						d1 = (d4 + d7) * -58981; d4 *= 19571; d7 *= 98391; d4 += d1; d7 += d1;
1210
1211						d1 = (d5 + d6) * -167963; d5 *= 134553; d6 *= 201373; d5 += d1; d6 += d1;
1212
1213						d4 += d2; d5 += d3; d6 += d2; d7 += d3;
1214
1215						//even
1216
1217						d3 = dataRef[2]; d2 = dataRef[6];
1218
1219						d1 = (d3 + d2) * 35468; d3 *= 50159; d2 *= -121095; d3 += d1; d2 += d1;
1220
1221						d0 = dataRef[0] + dataRef[4]; d1 = dataRef[0] - dataRef[4];
1222
1223						d0 = (d0 << 16) + 4096; d1 = (d1 << 16) + 4096;
1224
1225						tmp = d0 + d3; d3 = d0 - d3; d0 = tmp;
1226
1227						tmp = d1 + d2; d2 = d1 - d2; d1 = tmp;
1228
1229						tmp = d0 + d7; d7 = d0 - d7; d0 = tmp;
1230
1231						dataRef[0] = cast(short)(d0 >> 13); dataRef[7] = cast(short)(d7 >> 13);
1232
1233						d0 = d1 + d6; d6 = d1 - d6; d1 = d0;
1234
1235						dataRef[1] = cast(short)(d1 >> 13); dataRef[6] = cast(short)(d6 >> 13);
1236
1237						d0 = d2 + d5; d5 = d2 - d5; d2 = d0;
1238
1239						dataRef[2] = cast(short)(d2 >> 13); dataRef[5] = cast(short)(d5 >> 13);
1240
1241						d0 = d3 + d4; d4 = d3 - d4; d3 = d0;
1242
1243						dataRef[3] = cast(short)(d3 >> 13); dataRef[4] = cast(short)(d4 >> 13);
1244
1245						dataRef += 8;
1246					}
1247
1248					dataRef = &sof_comp[component_counter].data[data_start_pos];
1249
1250					for (int o=0; o<8; o++) {
1251						// odd
1252
1253						d4 = dataRef[56]; d5 = dataRef[40]; d6 = dataRef[24]; d7 = dataRef[8];
1254
1255						d2 = d4 + d6; d3 = d5 + d7;
1256
1257						d1 = (d2 + d3) * 77062; d2 *= -128553; d3 *= -25571; d2 += d1; d3 += d1;
1258
1259						d1 = (d4 + d7) * -58981; d4 *= 19571; d7 *= 98391; d4 += d1; d7 += d1;
1260
1261						d1 = (d5 + d6) * -167963; d5 *= 134553; d6 *= 201373; d5 += d1; d6 += d1;
1262
1263						d4 += d2; d5 += d3; d6 += d2; d7 += d3;
1264
1265						// even
1266
1267						d3 = dataRef[2*8]; d2 = dataRef[6*8];
1268
1269						d1 = (d3 + d2) * 35468; d3 *= 50159; d2 *= -121095; d3 += d1; d2 += d1;
1270
1271						d0 = dataRef[0] + dataRef[32]; d1 = dataRef[0] - dataRef[32];
1272
1273						d0 = (d0 << 16) + 2097152; d1 = (d1 << 16) + 2097152;
1274
1275						tmp = d0 + d3; d3 = d0 - d3; d0 = tmp;
1276
1277						tmp = d1 + d2; d2 = d1 - d2; d1 = tmp;
1278
1279						tmp = d0 + d7; d7 = d0 - d7; d0 = tmp;
1280
1281						//the 128 is part of the rescaling process of JPEG
1282						//and is not part of the IDCT algorithm
1283
1284						//526870912 is 128 << 22
1285
1286						d0 += (128 << 22); dataRef[0] = cast(short)(d0 >> 22) ;
1287						if (dataRef[0] > 255) { dataRef[0] = 255; } else if (dataRef[0] < 0) { dataRef[0] = 0;}
1288
1289						d7 += (128 << 22); dataRef[56] = cast(short)(d7 >> 22) ;
1290						if (dataRef[56] > 255) { dataRef[56] = 255; } else if (dataRef[56] < 0) { dataRef[56] = 0;}
1291
1292						d0 = d1 + d6; d6 = d1 - d6; d1 = d0;
1293
1294						d1 += (128 << 22); dataRef[8] = cast(short)(d1 >> 22) ;
1295						if (dataRef[8] > 255) { dataRef[8] = 255; } else if (dataRef[8] < 0) { dataRef[8] = 0;}
1296
1297						d6 += (128 << 22); dataRef[48] = cast(short)(d6 >> 22) ;
1298						if (dataRef[48] > 255) { dataRef[48] = 255; } else if (dataRef[48] < 0) { dataRef[48] = 0;}
1299
1300						d0 = d2 + d5; d5 = d2 - d5; d2 = d0;
1301
1302						d2 += (128 << 22);
1303						dataRef[16] = cast(short)(d2 >> 22) ;
1304						if (dataRef[16] > 255) { dataRef[16] = 255; } else if (dataRef[16] < 0) { dataRef[16] = 0;}
1305
1306						d5 += (128 << 22); dataRef[40] = cast(short)(d5 >> 22) ;
1307						if (dataRef[40] > 255) { dataRef[40] = 255; } else if (dataRef[40] < 0) { dataRef[40] = 0;}
1308
1309						d0 = d3 + d4; d4 = d3 - d4; d3 = d0;
1310
1311						d3 += (128 << 22); dataRef[24] = cast(short)(d3 >> 22) ;
1312						if (dataRef[24] > 255) { dataRef[24] = 255; } else if (dataRef[24] < 0) { dataRef[24] = 0;}
1313
1314						d4 += (128 << 22); dataRef[32] = cast(short)(d4 >> 22) ;
1315						if (dataRef[32] > 255) { dataRef[32] = 255; } else if (dataRef[32] < 0) { dataRef[32] = 0;}
1316
1317						dataRef++;
1318					}
1319
1320					//the IDCT has been done...we now have uncompressed data for this 8x8, 8 bit component
1321
1322					//goto the next sample or next component to complete the scan
1323					component_sample_counter++;
1324					if (component_sample_counter == sof_comp[component_counter].HxV) {
1325						component_counter++;
1326						component_sample_counter=0;
1327					}
1328
1329					if (component_counter != sof.num_image_components) {
1330						// continue decoding components
1331						decoderState = JPEG_STATE_DECODE_HUFFMAN_INIT;
1332						continue;
1333					}
1334
1335					decoderState = JPEG_STATE_RENDER_MCU;
1336
1337					/* follow through */
1338
1339				case JPEG_STATE_RENDER_MCU:
1340
1341					//writefln("jpeg - render - mcu");
1342
1343					//we have decoded the MCU at this point
1344					//paint the MCU to the image
1345
1346					//now, for every 8x8 pixel block, we will take the 8x8 information we have to
1347					//place the RGB transformed pixels on the image
1348
1349					// LOCK the buffer, if it hasn't been locked yet
1350					if (intermediate_imgPos_Start is null) {
1351						view.lockBuffer(cast(void**)&intermediate_imgPos_Start, image_length);
1352					}
1353
1354					intermediate_imgPos_Start_MCU = intermediate_imgPos_Start + image_ptr_offset;
1355
1356					int d0=0;	//Y data index
1357					ushort* d0_pos;
1358					ushort* d1_pos;
1359					ushort* d2_pos;
1360
1361					int d3=255;	//Y scan component index
1362					int d4=255;	//Cb scan component index
1363					int d5=255;	//Cr scan component index
1364
1365					int a;
1366
1367					for (a=0; a<3; a++) {
1368						if (sof_comp[a].C == 1) {
1369							//Y component
1370							d0_pos = cast(ushort*)sof_comp[a].data.ptr;
1371							d3=a;
1372						}
1373						else if (sof_comp[a].C == 2) {
1374							//cb
1375							d1_pos = cast(ushort*)sof_comp[a].data.ptr;
1376							d4=a;
1377						}
1378						else if (sof_comp[a].C == 3) {
1379							//cr
1380							d2_pos = cast(ushort*)sof_comp[a].data.ptr;
1381							d5=a;
1382						}
1383					}
1384
1385					a=0;
1386
1387					while (a<Vmajor) {
1388						for (int q=0;q<Hmajor;q++) {
1389							//code will be run through for every 8x8 block represented by this MCU
1390							//in this order:
1391							// /-------\
1392							// | 1 | 2 |
1393							// |-------|	a 2x2 MCU (could also be 1x1, 1x2, or 2x1 in common situations)
1394							// | 3 | 4 |
1395							// \-------/
1396
1397							intermediate_imgPos = intermediate_imgPos_Start_MCU;
1398
1399
1400							float ab;
1401
1402							if (sof.num_image_components == 1) {
1403								for (int n=0; n<8; n++) {
1404									for (int p=0; p<8; p++) {
1405										ubyte r,g,b;
1406
1407										//write at the RGBA of intermediate_imgPos;
1408										r = g = b = (cast(ubyte)d0_pos[d0]);
1409
1410										*(cast(uint*)intermediate_imgPos) = view.rgbaTouint(r,g,b,0xFF);
1411
1412										d0++;
1413
1414										intermediate_imgPos+=4;
1415									}
1416									intermediate_imgPos+=imgylinemovement-32;
1417								}
1418							}
1419							else {
1420								for (int n=0; n<8; n++) {
1421									for (int p=0; p<8; p++) {
1422										ubyte r,g,b;
1423
1424										//write at the RGBA of intermediate_imgPos;
1425										ab = (cb_b_uncode[d1_pos[cb_upsample_lookup[d0]]] + cast(float)d0_pos[d0]);
1426										if (ab > 255) { ab = 255; }	else if (ab < 0) { ab = 0; }
1427										b = cast(ubyte)(ab);	//BB
1428
1429										ab = (cb_g_uncode[d1_pos[cb_upsample_lookup[d0]]] - cr_g_uncode[d2_pos[cr_upsample_lookup[d0]]] + cast(float)d0_pos[d0]);
1430										if (ab > 255) { ab = 255; }	else if (ab < 0) { ab = 0; }
1431										g = cast(ubyte)(ab);		//GG
1432
1433										ab = (cr_r_uncode[d2_pos[cr_upsample_lookup[d0]]] + cast(float)d0_pos[d0]);
1434										if (ab > 255) { ab = 255; }	else if (ab < 0) { ab = 0; }
1435										r = cast(ubyte)(ab);		//RR
1436
1437										*(cast(uint*)intermediate_imgPos) = view.rgbaTouint(r,g,b,0xFF);
1438
1439										d0++;
1440
1441										intermediate_imgPos+=4;
1442									}
1443									intermediate_imgPos+=imgylinemovement-32;
1444								}
1445							}
1446							//translate pixels, place on image buffer
1447
1448							//move over image pointer in the X direction
1449							intermediate_imgPos_Start_MCU+=32;
1450						} //end for (q)
1451
1452						//reset X direction
1453						//move down image pointer in the Y direction
1454						a++;
1455
1456						intermediate_imgPos_Start_MCU = intermediate_imgPos_Start + (image_ptr_offset + (a * imgylinemovement_block));
1457					} //end for (a)
1458
1459					//move image buffer pointer to point at coords of next MCU block
1460
1461					cur_block_x++;
1462					if (cur_block_x == block_width) {
1463						cur_block_x = 0;
1464						cur_block_y++;
1465
1466						image_ptr_offset = (cur_block_y * imgylinemovement_block_start);
1467
1468						if(cur_block_y == block_height) {
1469							//we should be done
1470							//we have decoded the frame
1471
1472							if (intermediate_imgPos_Start !is null) {
1473								intermediate_imgPos_Start = null;
1474								view.unlockBuffer();
1475							}
1476							return StreamData.Complete;
1477						}
1478					}
1479					else {
1480						image_ptr_offset += imgxlinemovement_block_start;
1481					}
1482
1483					component_counter=0;
1484
1485					decoderState = JPEG_STATE_DECODE_HUFFMAN_INIT;
1486					continue;
1487
1488				default:
1489					break;
1490			}
1491			break;
1492		}
1493		return StreamData.Invalid;
1494	}
1495
1496protected:
1497
1498	JPEG_RENDER_INFO jpeg_vars;
1499
1500	ushort chunkType;
1501	ushort chunkLength;
1502
1503	ushort bytesToRead;
1504
1505	JFIF_HEADER jfif;
1506
1507	JPEG_SOF sof;
1508	SCAN_COMPONENT_SELECTOR[] sof_comp;
1509
1510	JPEG_SOS sos;
1511	JPEG_SOS_COMPONENTS sos_comp;
1512	JPEG_SOS_SELECTOR sos_sel;
1513
1514	HUFFMAN_TABLE HT_DC[4];
1515	HUFFMAN_TABLE HT_AC[4];
1516
1517	HUFFMAN_TABLE* cur_ht;
1518
1519	int quantization_destination;
1520	int quantization_precision;
1521	ushort[64][4] quantization_table;
1522
1523	uint actual_image_width;
1524	uint actual_image_height;
1525
1526	uint block_width;
1527	uint block_height;
1528
1529	ubyte Hmajor;
1530	ubyte Vmajor;
1531
1532	ubyte[] cb_upsample_lookup;
1533	ubyte[] cr_upsample_lookup;
1534
1535	uint component_counter;
1536	uint component_sample_counter;
1537
1538	int data_start_pos;
1539
1540
1541	ubyte cur_bit_pos;
1542	ubyte cur_byte;
1543	ushort huffman_code;
1544	uint huffman_bits;
1545
1546	uint bits_to_read;
1547	ushort bits_read;
1548	uint first_bit;
1549
1550	uint cur_ac;
1551
1552	ubyte* intermediate_imgPos_Start;
1553	ubyte* intermediate_imgPos_Start_MCU;
1554	ubyte* intermediate_imgPos;
1555
1556	uint image_ptr_offset;
1557	ulong image_length;
1558
1559	uint imgylinemovement;
1560	uint imgylinemovement_block;
1561
1562	uint imgylinemovement_block_start;
1563	uint imgxlinemovement_block_start;
1564
1565	uint cur_block_x;
1566	uint cur_block_y;
1567}