Increased SPI frequency from 5Mhz to 10MHz

Fork of RA8875 by David Smart

Committer:
ItsJustZi
Date:
Mon Aug 21 22:00:31 2017 +0000
Revision:
150:13745364dba0
Parent:
136:224e03d5c31f
Turned SPI frequency back down to 5MHz for lower susceptibility to noise

Who changed what in which revision?

UserRevisionLine numberNew contents of line
WiredHome 115:c9862fd0c689 1 /*----------------------------------------------------------------------------/
WiredHome 115:c9862fd0c689 2 / TJpgDec - Tiny JPEG Decompressor R0.01b (C)ChaN, 2012
WiredHome 115:c9862fd0c689 3 /-----------------------------------------------------------------------------/
WiredHome 115:c9862fd0c689 4 / The TJpgDec is a generic JPEG decompressor module for tiny embedded systems.
WiredHome 115:c9862fd0c689 5 / This is a free software that opened for education, research and commercial
WiredHome 115:c9862fd0c689 6 / developments under license policy of following terms.
WiredHome 115:c9862fd0c689 7 /
WiredHome 115:c9862fd0c689 8 / Copyright (C) 2012, ChaN, all right reserved.
WiredHome 115:c9862fd0c689 9 /
WiredHome 115:c9862fd0c689 10 / * The TJpgDec module is a free software and there is NO WARRANTY.
WiredHome 115:c9862fd0c689 11 / * No restriction on use. You can use, modify and redistribute it for
WiredHome 115:c9862fd0c689 12 / personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY.
WiredHome 115:c9862fd0c689 13 / * Redistributions of source code must retain the above copyright notice.
WiredHome 115:c9862fd0c689 14 /
WiredHome 115:c9862fd0c689 15 /-----------------------------------------------------------------------------/
WiredHome 115:c9862fd0c689 16 / Oct 04,'11 R0.01 First release.
WiredHome 115:c9862fd0c689 17 / Feb 19,'12 R0.01a Fixed decompression fails when scan starts with an escape seq.
WiredHome 115:c9862fd0c689 18 / Sep 03,'12 R0.01b Added JD_TBLCLIP option.
WiredHome 115:c9862fd0c689 19 /----------------------------------------------------------------------------*/
WiredHome 115:c9862fd0c689 20
WiredHome 115:c9862fd0c689 21 #include "mbed.h"
WiredHome 115:c9862fd0c689 22
WiredHome 115:c9862fd0c689 23 #include "GraphicsDisplay.h"
WiredHome 115:c9862fd0c689 24
WiredHome 121:6bc4911f5e55 25 //#define DEBUG "JPEG"
WiredHome 115:c9862fd0c689 26 // ...
WiredHome 115:c9862fd0c689 27 // INFO("Stuff to show %d", var); // new-line is automatically appended
WiredHome 115:c9862fd0c689 28 //
WiredHome 115:c9862fd0c689 29 #if (defined(DEBUG) && !defined(TARGET_LPC11U24))
WiredHome 115:c9862fd0c689 30 #define INFO(x, ...) std::printf("[INF %s %4d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
WiredHome 115:c9862fd0c689 31 #define WARN(x, ...) std::printf("[WRN %s %4d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
WiredHome 115:c9862fd0c689 32 #define ERR(x, ...) std::printf("[ERR %s %4d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__);
WiredHome 115:c9862fd0c689 33 static void HexDump(const char * title, const uint8_t * p, int count)
WiredHome 115:c9862fd0c689 34 {
WiredHome 115:c9862fd0c689 35 int i;
WiredHome 115:c9862fd0c689 36 char buf[100] = "0000: ";
WiredHome 115:c9862fd0c689 37
WiredHome 115:c9862fd0c689 38 if (*title)
WiredHome 121:6bc4911f5e55 39 INFO("%s @%p", title, p);
WiredHome 115:c9862fd0c689 40 for (i=0; i<count; ) {
WiredHome 115:c9862fd0c689 41 sprintf(buf + strlen(buf), "%02X ", *(p+i));
WiredHome 115:c9862fd0c689 42 if ((++i & 0x0F) == 0x00) {
WiredHome 115:c9862fd0c689 43 INFO("%s", buf);
WiredHome 115:c9862fd0c689 44 if (i < count)
WiredHome 115:c9862fd0c689 45 sprintf(buf, "%04X: ", i);
WiredHome 115:c9862fd0c689 46 else
WiredHome 115:c9862fd0c689 47 buf[0] = '\0';
WiredHome 115:c9862fd0c689 48 }
WiredHome 115:c9862fd0c689 49 }
WiredHome 115:c9862fd0c689 50 if (strlen(buf))
WiredHome 115:c9862fd0c689 51 INFO("%s", buf);
WiredHome 115:c9862fd0c689 52 }
WiredHome 115:c9862fd0c689 53 #else
WiredHome 115:c9862fd0c689 54 #define INFO(x, ...)
WiredHome 115:c9862fd0c689 55 #define WARN(x, ...)
WiredHome 115:c9862fd0c689 56 #define ERR(x, ...)
WiredHome 115:c9862fd0c689 57 #define HexDump(a, b, c)
WiredHome 115:c9862fd0c689 58 #endif
WiredHome 115:c9862fd0c689 59
WiredHome 115:c9862fd0c689 60
WiredHome 115:c9862fd0c689 61 /*-----------------------------------------------*/
WiredHome 115:c9862fd0c689 62 /* Zigzag-order to raster-order conversion table */
WiredHome 115:c9862fd0c689 63 /*-----------------------------------------------*/
WiredHome 115:c9862fd0c689 64
WiredHome 115:c9862fd0c689 65 #define ZIG(n) Zig[n]
WiredHome 115:c9862fd0c689 66
WiredHome 115:c9862fd0c689 67 static
WiredHome 115:c9862fd0c689 68 const uint8_t Zig[64] = { /* Zigzag-order to raster-order conversion table */
WiredHome 115:c9862fd0c689 69 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5,
WiredHome 115:c9862fd0c689 70 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28,
WiredHome 115:c9862fd0c689 71 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
WiredHome 115:c9862fd0c689 72 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63
WiredHome 115:c9862fd0c689 73 };
WiredHome 115:c9862fd0c689 74
WiredHome 115:c9862fd0c689 75
WiredHome 115:c9862fd0c689 76
WiredHome 115:c9862fd0c689 77 /*-------------------------------------------------*/
WiredHome 115:c9862fd0c689 78 /* Input scale factor of Arai algorithm */
WiredHome 115:c9862fd0c689 79 /* (scaled up 16 bits for fixed point operations) */
WiredHome 115:c9862fd0c689 80 /*-------------------------------------------------*/
WiredHome 115:c9862fd0c689 81
WiredHome 115:c9862fd0c689 82 #define IPSF(n) Ipsf[n]
WiredHome 115:c9862fd0c689 83
WiredHome 115:c9862fd0c689 84 static
WiredHome 115:c9862fd0c689 85 const uint16_t Ipsf[64] = { /* See also aa_idct.png */
WiredHome 115:c9862fd0c689 86 (uint16_t)(1.00000*8192), (uint16_t)(1.38704*8192), (uint16_t)(1.30656*8192), (uint16_t)(1.17588*8192), (uint16_t)(1.00000*8192), (uint16_t)(0.78570*8192), (uint16_t)(0.54120*8192), (uint16_t)(0.27590*8192),
WiredHome 115:c9862fd0c689 87 (uint16_t)(1.38704*8192), (uint16_t)(1.92388*8192), (uint16_t)(1.81226*8192), (uint16_t)(1.63099*8192), (uint16_t)(1.38704*8192), (uint16_t)(1.08979*8192), (uint16_t)(0.75066*8192), (uint16_t)(0.38268*8192),
WiredHome 115:c9862fd0c689 88 (uint16_t)(1.30656*8192), (uint16_t)(1.81226*8192), (uint16_t)(1.70711*8192), (uint16_t)(1.53636*8192), (uint16_t)(1.30656*8192), (uint16_t)(1.02656*8192), (uint16_t)(0.70711*8192), (uint16_t)(0.36048*8192),
WiredHome 115:c9862fd0c689 89 (uint16_t)(1.17588*8192), (uint16_t)(1.63099*8192), (uint16_t)(1.53636*8192), (uint16_t)(1.38268*8192), (uint16_t)(1.17588*8192), (uint16_t)(0.92388*8192), (uint16_t)(0.63638*8192), (uint16_t)(0.32442*8192),
WiredHome 115:c9862fd0c689 90 (uint16_t)(1.00000*8192), (uint16_t)(1.38704*8192), (uint16_t)(1.30656*8192), (uint16_t)(1.17588*8192), (uint16_t)(1.00000*8192), (uint16_t)(0.78570*8192), (uint16_t)(0.54120*8192), (uint16_t)(0.27590*8192),
WiredHome 115:c9862fd0c689 91 (uint16_t)(0.78570*8192), (uint16_t)(1.08979*8192), (uint16_t)(1.02656*8192), (uint16_t)(0.92388*8192), (uint16_t)(0.78570*8192), (uint16_t)(0.61732*8192), (uint16_t)(0.42522*8192), (uint16_t)(0.21677*8192),
WiredHome 115:c9862fd0c689 92 (uint16_t)(0.54120*8192), (uint16_t)(0.75066*8192), (uint16_t)(0.70711*8192), (uint16_t)(0.63638*8192), (uint16_t)(0.54120*8192), (uint16_t)(0.42522*8192), (uint16_t)(0.29290*8192), (uint16_t)(0.14932*8192),
WiredHome 115:c9862fd0c689 93 (uint16_t)(0.27590*8192), (uint16_t)(0.38268*8192), (uint16_t)(0.36048*8192), (uint16_t)(0.32442*8192), (uint16_t)(0.27590*8192), (uint16_t)(0.21678*8192), (uint16_t)(0.14932*8192), (uint16_t)(0.07612*8192)
WiredHome 115:c9862fd0c689 94 };
WiredHome 115:c9862fd0c689 95
WiredHome 115:c9862fd0c689 96
WiredHome 115:c9862fd0c689 97
WiredHome 115:c9862fd0c689 98 /*---------------------------------------------*/
WiredHome 115:c9862fd0c689 99 /* Conversion table for fast clipping process */
WiredHome 115:c9862fd0c689 100 /*---------------------------------------------*/
WiredHome 115:c9862fd0c689 101
WiredHome 115:c9862fd0c689 102 #if JD_TBLCLIP
WiredHome 115:c9862fd0c689 103
WiredHome 115:c9862fd0c689 104 #define BYTECLIP(v) Clip8[(uint16_t)(v) & 0x3FF]
WiredHome 115:c9862fd0c689 105
WiredHome 115:c9862fd0c689 106 static
WiredHome 115:c9862fd0c689 107 const uint8_t Clip8[1024] = {
WiredHome 115:c9862fd0c689 108 /* 0..255 */
WiredHome 115:c9862fd0c689 109 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
WiredHome 115:c9862fd0c689 110 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
WiredHome 115:c9862fd0c689 111 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
WiredHome 115:c9862fd0c689 112 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
WiredHome 115:c9862fd0c689 113 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159,
WiredHome 115:c9862fd0c689 114 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
WiredHome 115:c9862fd0c689 115 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
WiredHome 115:c9862fd0c689 116 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255,
WiredHome 115:c9862fd0c689 117 /* 256..511 */
WiredHome 115:c9862fd0c689 118 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
WiredHome 115:c9862fd0c689 119 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
WiredHome 115:c9862fd0c689 120 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
WiredHome 115:c9862fd0c689 121 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
WiredHome 115:c9862fd0c689 122 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
WiredHome 115:c9862fd0c689 123 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
WiredHome 115:c9862fd0c689 124 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
WiredHome 115:c9862fd0c689 125 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
WiredHome 115:c9862fd0c689 126 /* -512..-257 */
WiredHome 115:c9862fd0c689 127 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
WiredHome 115:c9862fd0c689 128 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
WiredHome 115:c9862fd0c689 129 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
WiredHome 115:c9862fd0c689 130 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
WiredHome 115:c9862fd0c689 131 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
WiredHome 115:c9862fd0c689 132 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
WiredHome 115:c9862fd0c689 133 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
WiredHome 115:c9862fd0c689 134 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
WiredHome 115:c9862fd0c689 135 /* -256..-1 */
WiredHome 115:c9862fd0c689 136 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
WiredHome 115:c9862fd0c689 137 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
WiredHome 115:c9862fd0c689 138 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
WiredHome 115:c9862fd0c689 139 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
WiredHome 115:c9862fd0c689 140 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
WiredHome 115:c9862fd0c689 141 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
WiredHome 115:c9862fd0c689 142 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
WiredHome 115:c9862fd0c689 143 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
WiredHome 115:c9862fd0c689 144 };
WiredHome 115:c9862fd0c689 145
WiredHome 115:c9862fd0c689 146 #else /* JD_TBLCLIP */
WiredHome 115:c9862fd0c689 147
WiredHome 115:c9862fd0c689 148 inline
WiredHome 115:c9862fd0c689 149 uint8_t BYTECLIP (
WiredHome 115:c9862fd0c689 150 int16_t val
WiredHome 115:c9862fd0c689 151 )
WiredHome 115:c9862fd0c689 152 {
WiredHome 115:c9862fd0c689 153 if (val < 0) val = 0;
WiredHome 115:c9862fd0c689 154 if (val > 255) val = 255;
WiredHome 115:c9862fd0c689 155
WiredHome 115:c9862fd0c689 156 return (uint8_t)val;
WiredHome 115:c9862fd0c689 157 }
WiredHome 115:c9862fd0c689 158
WiredHome 115:c9862fd0c689 159 #endif
WiredHome 115:c9862fd0c689 160
WiredHome 115:c9862fd0c689 161
WiredHome 115:c9862fd0c689 162
WiredHome 115:c9862fd0c689 163 /*-----------------------------------------------------------------------*/
WiredHome 115:c9862fd0c689 164 /* Allocate a memory block from memory pool */
WiredHome 115:c9862fd0c689 165 /*-----------------------------------------------------------------------*/
WiredHome 115:c9862fd0c689 166
WiredHome 115:c9862fd0c689 167 static
WiredHome 115:c9862fd0c689 168 void* alloc_pool ( /* Pointer to allocated memory block (NULL:no memory available) */
WiredHome 115:c9862fd0c689 169 JDEC * jd, /* Pointer to the decompressor object */
WiredHome 115:c9862fd0c689 170 uint16_t nd /* Number of bytes to allocate */
WiredHome 115:c9862fd0c689 171 )
WiredHome 115:c9862fd0c689 172 {
WiredHome 115:c9862fd0c689 173 char *rp = 0;
WiredHome 115:c9862fd0c689 174
WiredHome 115:c9862fd0c689 175 INFO("alloc_pool(%p,%d) %p:%d", jd, nd, jd->pool, jd->sz_pool);
WiredHome 115:c9862fd0c689 176 nd = (nd + 3) & ~3; /* Align block size to the word boundary */
WiredHome 115:c9862fd0c689 177
WiredHome 115:c9862fd0c689 178 if (jd->sz_pool >= nd) {
WiredHome 115:c9862fd0c689 179 jd->sz_pool -= nd;
WiredHome 115:c9862fd0c689 180 rp = (char*)jd->pool; /* Get start of available memory pool */
WiredHome 115:c9862fd0c689 181 jd->pool = (void*)(rp + nd); /* Allocate requierd bytes */
WiredHome 120:be2aaa3adf72 182 //INFO("jd->pool %p", jd->pool);
WiredHome 115:c9862fd0c689 183 }
WiredHome 115:c9862fd0c689 184 INFO("rp %p", rp);
WiredHome 115:c9862fd0c689 185 return (void*)rp; /* Return allocated memory block (NULL:no memory to allocate) */
WiredHome 115:c9862fd0c689 186 }
WiredHome 115:c9862fd0c689 187
WiredHome 115:c9862fd0c689 188
WiredHome 115:c9862fd0c689 189
WiredHome 115:c9862fd0c689 190
WiredHome 115:c9862fd0c689 191 /*-----------------------------------------------------------------------*/
WiredHome 115:c9862fd0c689 192 /* Create de-quantization and prescaling tables with a DQT segment */
WiredHome 115:c9862fd0c689 193 /*-----------------------------------------------------------------------*/
WiredHome 115:c9862fd0c689 194
WiredHome 115:c9862fd0c689 195 static
WiredHome 115:c9862fd0c689 196 uint16_t create_qt_tbl ( /* 0:OK, !0:Failed */
WiredHome 115:c9862fd0c689 197 JDEC * jd, /* Pointer to the decompressor object */
WiredHome 115:c9862fd0c689 198 const uint8_t * data, /* Pointer to the quantizer tables */
WiredHome 115:c9862fd0c689 199 uint16_t ndata /* Size of input data */
WiredHome 115:c9862fd0c689 200 )
WiredHome 115:c9862fd0c689 201 {
WiredHome 115:c9862fd0c689 202 uint16_t i;
WiredHome 115:c9862fd0c689 203 uint8_t d, z;
WiredHome 115:c9862fd0c689 204 int32_t *pb;
WiredHome 115:c9862fd0c689 205
WiredHome 120:be2aaa3adf72 206 INFO("create qt table (%p,%p,%d)", jd, data, ndata);
WiredHome 120:be2aaa3adf72 207 HexDump("JDEC", (uint8_t *)jd, sizeof(JDEC));
WiredHome 115:c9862fd0c689 208 while (ndata) { /* Process all tables in the segment */
WiredHome 115:c9862fd0c689 209 if (ndata < 65) return JDR_FMT1; /* Err: table size is unaligned */
WiredHome 115:c9862fd0c689 210 ndata -= 65;
WiredHome 115:c9862fd0c689 211 d = *data++; /* Get table property */
WiredHome 115:c9862fd0c689 212 if (d & 0xF0) return JDR_FMT1; /* Err: not 8-bit resolution */
WiredHome 115:c9862fd0c689 213 i = d & 3; /* Get table ID */
WiredHome 115:c9862fd0c689 214 pb = (int32_t *)alloc_pool(jd, 64 * sizeof (int32_t));/* Allocate a memory block for the table */
WiredHome 115:c9862fd0c689 215 if (!pb) return JDR_MEM1; /* Err: not enough memory */
WiredHome 115:c9862fd0c689 216 jd->qttbl[i] = pb; /* Register the table */
WiredHome 115:c9862fd0c689 217 for (i = 0; i < 64; i++) { /* Load the table */
WiredHome 115:c9862fd0c689 218 z = ZIG(i); /* Zigzag-order to raster-order conversion */
WiredHome 115:c9862fd0c689 219 pb[z] = (int32_t)((uint32_t)*data++ * IPSF(z)); /* Apply scale factor of Arai algorithm to the de-quantizers */
WiredHome 115:c9862fd0c689 220 }
WiredHome 115:c9862fd0c689 221 }
WiredHome 115:c9862fd0c689 222
WiredHome 115:c9862fd0c689 223 return JDR_OK;
WiredHome 115:c9862fd0c689 224 }
WiredHome 115:c9862fd0c689 225
WiredHome 115:c9862fd0c689 226
WiredHome 115:c9862fd0c689 227
WiredHome 115:c9862fd0c689 228
WiredHome 115:c9862fd0c689 229 /*-----------------------------------------------------------------------*/
WiredHome 115:c9862fd0c689 230 /* Create huffman code tables with a DHT segment */
WiredHome 115:c9862fd0c689 231 /*-----------------------------------------------------------------------*/
WiredHome 115:c9862fd0c689 232
WiredHome 115:c9862fd0c689 233 static
WiredHome 115:c9862fd0c689 234 uint16_t create_huffman_tbl ( /* 0:OK, !0:Failed */
WiredHome 115:c9862fd0c689 235 JDEC * jd, /* Pointer to the decompressor object */
WiredHome 115:c9862fd0c689 236 const uint8_t * data, /* Pointer to the packed huffman tables */
WiredHome 115:c9862fd0c689 237 uint16_t ndata /* Size of input data */
WiredHome 115:c9862fd0c689 238 )
WiredHome 115:c9862fd0c689 239 {
WiredHome 115:c9862fd0c689 240 uint16_t i, j, b, np, cls, num;
WiredHome 115:c9862fd0c689 241 uint8_t d, *pb, *pd;
WiredHome 115:c9862fd0c689 242 uint16_t hc, *ph;
WiredHome 115:c9862fd0c689 243
WiredHome 117:6710b8e196f0 244 INFO("create_huffman_tbl(%p,%p,%d)", jd, data, ndata);
WiredHome 121:6bc4911f5e55 245 HexDump("JDEC - create_huffman_tbl entry", (uint8_t *)jd, sizeof(JDEC));
WiredHome 115:c9862fd0c689 246 while (ndata) { /* Process all tables in the segment */
WiredHome 115:c9862fd0c689 247 if (ndata < 17) return JDR_FMT1; /* Err: wrong data size */
WiredHome 115:c9862fd0c689 248 ndata -= 17;
WiredHome 115:c9862fd0c689 249 d = *data++; /* Get table number and class */
WiredHome 115:c9862fd0c689 250 cls = (d >> 4); num = d & 0x0F; /* class = dc(0)/ac(1), table number = 0/1 */
WiredHome 115:c9862fd0c689 251 if (d & 0xEE) return JDR_FMT1; /* Err: invalid class/number */
WiredHome 115:c9862fd0c689 252 pb = (uint8_t *)alloc_pool(jd, 16); /* Allocate a memory block for the bit distribution table */
WiredHome 115:c9862fd0c689 253 if (!pb) {
WiredHome 115:c9862fd0c689 254 ERR("JDR_MEM1");
WiredHome 115:c9862fd0c689 255 return JDR_MEM1; /* Err: not enough memory */
WiredHome 115:c9862fd0c689 256 }
WiredHome 115:c9862fd0c689 257 jd->huffbits[num][cls] = pb;
WiredHome 115:c9862fd0c689 258 for (np = i = 0; i < 16; i++) { /* Load number of patterns for 1 to 16-bit code */
WiredHome 115:c9862fd0c689 259 pb[i] = b = *data++;
WiredHome 115:c9862fd0c689 260 np += b; /* Get sum of code words for each code */
WiredHome 115:c9862fd0c689 261 }
WiredHome 115:c9862fd0c689 262
WiredHome 115:c9862fd0c689 263 ph = (uint16_t *)alloc_pool(jd, np * sizeof (uint16_t));/* Allocate a memory block for the code word table */
WiredHome 115:c9862fd0c689 264 if (!ph) {
WiredHome 115:c9862fd0c689 265 ERR("JDR_MEM1");
WiredHome 115:c9862fd0c689 266 return JDR_MEM1; /* Err: not enough memory */
WiredHome 115:c9862fd0c689 267 }
WiredHome 118:34eb0b64fc61 268 //INFO("jd->pool: %p", jd->pool);
WiredHome 115:c9862fd0c689 269 jd->huffcode[num][cls] = ph;
WiredHome 118:34eb0b64fc61 270 //INFO("jd->pool: %p, %p", jd->pool, ph);
WiredHome 115:c9862fd0c689 271 hc = 0;
WiredHome 115:c9862fd0c689 272 for (j = i = 0; i < 16; i++) { /* Re-build huffman code word table */
WiredHome 115:c9862fd0c689 273 b = pb[i];
WiredHome 115:c9862fd0c689 274 while (b--) ph[j++] = hc++;
WiredHome 115:c9862fd0c689 275 hc <<= 1;
WiredHome 115:c9862fd0c689 276 INFO("jd->pool: %d: %p, %p", i, jd->pool, ph);
WiredHome 115:c9862fd0c689 277 }
WiredHome 118:34eb0b64fc61 278 //INFO("jd->pool: %p", jd->pool);
WiredHome 115:c9862fd0c689 279
WiredHome 115:c9862fd0c689 280 if (ndata < np) return JDR_FMT1; /* Err: wrong data size */
WiredHome 115:c9862fd0c689 281 ndata -= np;
WiredHome 118:34eb0b64fc61 282 //INFO("jd->pool: %p", jd->pool);
WiredHome 115:c9862fd0c689 283 pd = (uint8_t *)alloc_pool(jd, np); /* Allocate a memory block for the decoded data */
WiredHome 118:34eb0b64fc61 284 //INFO("jd->pool: %p", jd->pool);
WiredHome 115:c9862fd0c689 285 if (!pd) {
WiredHome 115:c9862fd0c689 286 ERR("JDR_MEM1");
WiredHome 115:c9862fd0c689 287 return JDR_MEM1; /* Err: not enough memory */
WiredHome 115:c9862fd0c689 288 }
WiredHome 115:c9862fd0c689 289 jd->huffdata[num][cls] = pd;
WiredHome 115:c9862fd0c689 290 for (i = 0; i < np; i++) { /* Load decoded data corresponds to each code ward */
WiredHome 115:c9862fd0c689 291 d = *data++;
WiredHome 115:c9862fd0c689 292 if (!cls && d > 11) return JDR_FMT1;
WiredHome 115:c9862fd0c689 293 *pd++ = d;
WiredHome 115:c9862fd0c689 294 }
WiredHome 115:c9862fd0c689 295 }
WiredHome 115:c9862fd0c689 296
WiredHome 121:6bc4911f5e55 297 HexDump("JDEC - create_huffman_tbl exit", (uint8_t *)jd, sizeof(JDEC));
WiredHome 115:c9862fd0c689 298 return JDR_OK;
WiredHome 115:c9862fd0c689 299 }
WiredHome 115:c9862fd0c689 300
WiredHome 115:c9862fd0c689 301
WiredHome 115:c9862fd0c689 302
WiredHome 115:c9862fd0c689 303
WiredHome 115:c9862fd0c689 304 /*-----------------------------------------------------------------------*/
WiredHome 115:c9862fd0c689 305 /* Extract N bits from input stream */
WiredHome 115:c9862fd0c689 306 /*-----------------------------------------------------------------------*/
WiredHome 115:c9862fd0c689 307
WiredHome 115:c9862fd0c689 308 int16_t GraphicsDisplay::bitext ( /* >=0: extracted data, <0: error code */
WiredHome 115:c9862fd0c689 309 JDEC * jd, /* Pointer to the decompressor object */
WiredHome 115:c9862fd0c689 310 uint16_t nbit /* Number of bits to extract (1 to 11) */
WiredHome 115:c9862fd0c689 311 )
WiredHome 115:c9862fd0c689 312 {
WiredHome 115:c9862fd0c689 313 uint8_t msk, s, *dp;
WiredHome 115:c9862fd0c689 314 uint16_t dc, v, f;
WiredHome 115:c9862fd0c689 315
WiredHome 115:c9862fd0c689 316
WiredHome 115:c9862fd0c689 317 msk = jd->dmsk; dc = jd->dctr; dp = jd->dptr; /* Bit mask, number of data available, read ptr */
WiredHome 115:c9862fd0c689 318 s = *dp; v = f = 0;
WiredHome 115:c9862fd0c689 319 do {
WiredHome 115:c9862fd0c689 320 if (!msk) { /* Next byte? */
WiredHome 115:c9862fd0c689 321 if (!dc) { /* No input data is available, re-fill input buffer */
WiredHome 115:c9862fd0c689 322 dp = jd->inbuf; /* Top of input buffer */
WiredHome 115:c9862fd0c689 323 dc = getJpegData(jd, dp, JD_SZBUF);
WiredHome 115:c9862fd0c689 324 if (!dc) return 0 - (int16_t)JDR_INP; /* Err: read error or wrong stream termination */
WiredHome 115:c9862fd0c689 325 } else {
WiredHome 115:c9862fd0c689 326 dp++; /* Next data ptr */
WiredHome 115:c9862fd0c689 327 }
WiredHome 115:c9862fd0c689 328 dc--; /* Decrement number of available bytes */
WiredHome 115:c9862fd0c689 329 if (f) { /* In flag sequence? */
WiredHome 115:c9862fd0c689 330 f = 0; /* Exit flag sequence */
WiredHome 115:c9862fd0c689 331 if (*dp != 0) return 0 - (int16_t)JDR_FMT1; /* Err: unexpected flag is detected (may be collapted data) */
WiredHome 115:c9862fd0c689 332 *dp = s = 0xFF; /* The flag is a data 0xFF */
WiredHome 115:c9862fd0c689 333 } else {
WiredHome 115:c9862fd0c689 334 s = *dp; /* Get next data byte */
WiredHome 115:c9862fd0c689 335 if (s == 0xFF) { /* Is start of flag sequence? */
WiredHome 115:c9862fd0c689 336 f = 1; continue; /* Enter flag sequence */
WiredHome 115:c9862fd0c689 337 }
WiredHome 115:c9862fd0c689 338 }
WiredHome 115:c9862fd0c689 339 msk = 0x80; /* Read from MSB */
WiredHome 115:c9862fd0c689 340 }
WiredHome 115:c9862fd0c689 341 v <<= 1; /* Get a bit */
WiredHome 115:c9862fd0c689 342 if (s & msk) v++;
WiredHome 115:c9862fd0c689 343 msk >>= 1;
WiredHome 115:c9862fd0c689 344 nbit--;
WiredHome 115:c9862fd0c689 345 } while (nbit);
WiredHome 115:c9862fd0c689 346 jd->dmsk = msk; jd->dctr = dc; jd->dptr = dp;
WiredHome 115:c9862fd0c689 347
WiredHome 115:c9862fd0c689 348 return (int16_t)v;
WiredHome 115:c9862fd0c689 349 }
WiredHome 115:c9862fd0c689 350
WiredHome 115:c9862fd0c689 351
WiredHome 115:c9862fd0c689 352
WiredHome 115:c9862fd0c689 353
WiredHome 115:c9862fd0c689 354 /*-----------------------------------------------------------------------*/
WiredHome 115:c9862fd0c689 355 /* Extract a huffman decoded data from input stream */
WiredHome 115:c9862fd0c689 356 /*-----------------------------------------------------------------------*/
WiredHome 115:c9862fd0c689 357
WiredHome 115:c9862fd0c689 358 int16_t GraphicsDisplay::huffext ( /* >=0: decoded data, <0: error code */
WiredHome 115:c9862fd0c689 359 JDEC * jd, /* Pointer to the decompressor object */
WiredHome 115:c9862fd0c689 360 const uint8_t * hbits, /* Pointer to the bit distribution table */
WiredHome 115:c9862fd0c689 361 const uint16_t * hcode, /* Pointer to the code word table */
WiredHome 115:c9862fd0c689 362 const uint8_t * hdata /* Pointer to the data table */
WiredHome 115:c9862fd0c689 363 )
WiredHome 115:c9862fd0c689 364 {
WiredHome 115:c9862fd0c689 365 uint8_t msk, s, *dp;
WiredHome 115:c9862fd0c689 366 uint16_t dc, v, f, bl, nd;
WiredHome 115:c9862fd0c689 367
WiredHome 115:c9862fd0c689 368
WiredHome 115:c9862fd0c689 369 msk = jd->dmsk; dc = jd->dctr; dp = jd->dptr; /* Bit mask, number of data available, read ptr */
WiredHome 115:c9862fd0c689 370 s = *dp; v = f = 0;
WiredHome 115:c9862fd0c689 371 bl = 16; /* Max code length */
WiredHome 115:c9862fd0c689 372 do {
WiredHome 115:c9862fd0c689 373 if (!msk) { /* Next byte? */
WiredHome 115:c9862fd0c689 374 if (!dc) { /* No input data is available, re-fill input buffer */
WiredHome 115:c9862fd0c689 375 dp = jd->inbuf; /* Top of input buffer */
WiredHome 115:c9862fd0c689 376 dc = getJpegData(jd, dp, JD_SZBUF);
WiredHome 115:c9862fd0c689 377 if (!dc) return 0 - (int16_t)JDR_INP; /* Err: read error or wrong stream termination */
WiredHome 115:c9862fd0c689 378 } else {
WiredHome 115:c9862fd0c689 379 dp++; /* Next data ptr */
WiredHome 115:c9862fd0c689 380 }
WiredHome 115:c9862fd0c689 381 dc--; /* Decrement number of available bytes */
WiredHome 115:c9862fd0c689 382 if (f) { /* In flag sequence? */
WiredHome 115:c9862fd0c689 383 f = 0; /* Exit flag sequence */
WiredHome 115:c9862fd0c689 384 if (*dp != 0)
WiredHome 115:c9862fd0c689 385 return 0 - (int16_t)JDR_FMT1; /* Err: unexpected flag is detected (may be collapted data) */
WiredHome 115:c9862fd0c689 386 *dp = s = 0xFF; /* The flag is a data 0xFF */
WiredHome 115:c9862fd0c689 387 } else {
WiredHome 115:c9862fd0c689 388 s = *dp; /* Get next data byte */
WiredHome 115:c9862fd0c689 389 if (s == 0xFF) { /* Is start of flag sequence? */
WiredHome 115:c9862fd0c689 390 f = 1; continue; /* Enter flag sequence, get trailing byte */
WiredHome 115:c9862fd0c689 391 }
WiredHome 115:c9862fd0c689 392 }
WiredHome 115:c9862fd0c689 393 msk = 0x80; /* Read from MSB */
WiredHome 115:c9862fd0c689 394 }
WiredHome 115:c9862fd0c689 395 v <<= 1; /* Get a bit */
WiredHome 115:c9862fd0c689 396 if (s & msk) v++;
WiredHome 115:c9862fd0c689 397 msk >>= 1;
WiredHome 115:c9862fd0c689 398
WiredHome 115:c9862fd0c689 399 for (nd = *hbits++; nd; nd--) { /* Search the code word in this bit length */
WiredHome 115:c9862fd0c689 400 if (v == *hcode++) { /* Matched? */
WiredHome 115:c9862fd0c689 401 jd->dmsk = msk; jd->dctr = dc; jd->dptr = dp;
WiredHome 115:c9862fd0c689 402 return *hdata; /* Return the decoded data */
WiredHome 115:c9862fd0c689 403 }
WiredHome 115:c9862fd0c689 404 hdata++;
WiredHome 115:c9862fd0c689 405 }
WiredHome 115:c9862fd0c689 406 bl--;
WiredHome 115:c9862fd0c689 407 } while (bl);
WiredHome 115:c9862fd0c689 408
WiredHome 115:c9862fd0c689 409 return 0 - (int16_t)JDR_FMT1; /* Err: code not found (may be collapted data) */
WiredHome 115:c9862fd0c689 410 }
WiredHome 115:c9862fd0c689 411
WiredHome 115:c9862fd0c689 412
WiredHome 115:c9862fd0c689 413
WiredHome 115:c9862fd0c689 414
WiredHome 115:c9862fd0c689 415 /*-----------------------------------------------------------------------*/
WiredHome 115:c9862fd0c689 416 /* Apply Inverse-DCT in Arai Algorithm (see also aa_idct.png) */
WiredHome 115:c9862fd0c689 417 /*-----------------------------------------------------------------------*/
WiredHome 115:c9862fd0c689 418
WiredHome 115:c9862fd0c689 419 static
WiredHome 115:c9862fd0c689 420 void block_idct (
WiredHome 115:c9862fd0c689 421 int32_t * src, /* Input block data (de-quantized and pre-scaled for Arai Algorithm) */
WiredHome 115:c9862fd0c689 422 uint8_t * dst /* Pointer to the destination to store the block as byte array */
WiredHome 115:c9862fd0c689 423 )
WiredHome 115:c9862fd0c689 424 {
WiredHome 115:c9862fd0c689 425 const int32_t M13 = (int32_t)(1.41421*4096), M2 = (int32_t)(1.08239*4096), M4 = (int32_t)(2.61313*4096), M5 = (int32_t)(1.84776*4096);
WiredHome 115:c9862fd0c689 426 int32_t v0, v1, v2, v3, v4, v5, v6, v7;
WiredHome 115:c9862fd0c689 427 int32_t t10, t11, t12, t13;
WiredHome 115:c9862fd0c689 428 uint16_t i;
WiredHome 115:c9862fd0c689 429
WiredHome 115:c9862fd0c689 430 /* Process columns */
WiredHome 115:c9862fd0c689 431 for (i = 0; i < 8; i++) {
WiredHome 115:c9862fd0c689 432 v0 = src[8 * 0]; /* Get even elements */
WiredHome 115:c9862fd0c689 433 v1 = src[8 * 2];
WiredHome 115:c9862fd0c689 434 v2 = src[8 * 4];
WiredHome 115:c9862fd0c689 435 v3 = src[8 * 6];
WiredHome 115:c9862fd0c689 436
WiredHome 115:c9862fd0c689 437 t10 = v0 + v2; /* Process the even elements */
WiredHome 115:c9862fd0c689 438 t12 = v0 - v2;
WiredHome 115:c9862fd0c689 439 t11 = (v1 - v3) * M13 >> 12;
WiredHome 115:c9862fd0c689 440 v3 += v1;
WiredHome 115:c9862fd0c689 441 t11 -= v3;
WiredHome 115:c9862fd0c689 442 v0 = t10 + v3;
WiredHome 115:c9862fd0c689 443 v3 = t10 - v3;
WiredHome 115:c9862fd0c689 444 v1 = t11 + t12;
WiredHome 115:c9862fd0c689 445 v2 = t12 - t11;
WiredHome 115:c9862fd0c689 446
WiredHome 115:c9862fd0c689 447 v4 = src[8 * 7]; /* Get odd elements */
WiredHome 115:c9862fd0c689 448 v5 = src[8 * 1];
WiredHome 115:c9862fd0c689 449 v6 = src[8 * 5];
WiredHome 115:c9862fd0c689 450 v7 = src[8 * 3];
WiredHome 115:c9862fd0c689 451
WiredHome 115:c9862fd0c689 452 t10 = v5 - v4; /* Process the odd elements */
WiredHome 115:c9862fd0c689 453 t11 = v5 + v4;
WiredHome 115:c9862fd0c689 454 t12 = v6 - v7;
WiredHome 115:c9862fd0c689 455 v7 += v6;
WiredHome 115:c9862fd0c689 456 v5 = (t11 - v7) * M13 >> 12;
WiredHome 115:c9862fd0c689 457 v7 += t11;
WiredHome 115:c9862fd0c689 458 t13 = (t10 + t12) * M5 >> 12;
WiredHome 115:c9862fd0c689 459 v4 = t13 - (t10 * M2 >> 12);
WiredHome 115:c9862fd0c689 460 v6 = t13 - (t12 * M4 >> 12) - v7;
WiredHome 115:c9862fd0c689 461 v5 -= v6;
WiredHome 115:c9862fd0c689 462 v4 -= v5;
WiredHome 115:c9862fd0c689 463
WiredHome 115:c9862fd0c689 464 src[8 * 0] = v0 + v7; /* Write-back transformed values */
WiredHome 115:c9862fd0c689 465 src[8 * 7] = v0 - v7;
WiredHome 115:c9862fd0c689 466 src[8 * 1] = v1 + v6;
WiredHome 115:c9862fd0c689 467 src[8 * 6] = v1 - v6;
WiredHome 115:c9862fd0c689 468 src[8 * 2] = v2 + v5;
WiredHome 115:c9862fd0c689 469 src[8 * 5] = v2 - v5;
WiredHome 115:c9862fd0c689 470 src[8 * 3] = v3 + v4;
WiredHome 115:c9862fd0c689 471 src[8 * 4] = v3 - v4;
WiredHome 115:c9862fd0c689 472
WiredHome 115:c9862fd0c689 473 src++; /* Next column */
WiredHome 115:c9862fd0c689 474 }
WiredHome 115:c9862fd0c689 475
WiredHome 115:c9862fd0c689 476 /* Process rows */
WiredHome 115:c9862fd0c689 477 src -= 8;
WiredHome 115:c9862fd0c689 478 for (i = 0; i < 8; i++) {
WiredHome 115:c9862fd0c689 479 v0 = src[0] + (128L << 8); /* Get even elements (remove DC offset (-128) here) */
WiredHome 115:c9862fd0c689 480 v1 = src[2];
WiredHome 115:c9862fd0c689 481 v2 = src[4];
WiredHome 115:c9862fd0c689 482 v3 = src[6];
WiredHome 115:c9862fd0c689 483
WiredHome 115:c9862fd0c689 484 t10 = v0 + v2; /* Process the even elements */
WiredHome 115:c9862fd0c689 485 t12 = v0 - v2;
WiredHome 115:c9862fd0c689 486 t11 = (v1 - v3) * M13 >> 12;
WiredHome 115:c9862fd0c689 487 v3 += v1;
WiredHome 115:c9862fd0c689 488 t11 -= v3;
WiredHome 115:c9862fd0c689 489 v0 = t10 + v3;
WiredHome 115:c9862fd0c689 490 v3 = t10 - v3;
WiredHome 115:c9862fd0c689 491 v1 = t11 + t12;
WiredHome 115:c9862fd0c689 492 v2 = t12 - t11;
WiredHome 115:c9862fd0c689 493
WiredHome 115:c9862fd0c689 494 v4 = src[7]; /* Get odd elements */
WiredHome 115:c9862fd0c689 495 v5 = src[1];
WiredHome 115:c9862fd0c689 496 v6 = src[5];
WiredHome 115:c9862fd0c689 497 v7 = src[3];
WiredHome 115:c9862fd0c689 498
WiredHome 115:c9862fd0c689 499 t10 = v5 - v4; /* Process the odd elements */
WiredHome 115:c9862fd0c689 500 t11 = v5 + v4;
WiredHome 115:c9862fd0c689 501 t12 = v6 - v7;
WiredHome 115:c9862fd0c689 502 v7 += v6;
WiredHome 115:c9862fd0c689 503 v5 = (t11 - v7) * M13 >> 12;
WiredHome 115:c9862fd0c689 504 v7 += t11;
WiredHome 115:c9862fd0c689 505 t13 = (t10 + t12) * M5 >> 12;
WiredHome 115:c9862fd0c689 506 v4 = t13 - (t10 * M2 >> 12);
WiredHome 115:c9862fd0c689 507 v6 = t13 - (t12 * M4 >> 12) - v7;
WiredHome 115:c9862fd0c689 508 v5 -= v6;
WiredHome 115:c9862fd0c689 509 v4 -= v5;
WiredHome 115:c9862fd0c689 510
WiredHome 115:c9862fd0c689 511 dst[0] = BYTECLIP((v0 + v7) >> 8); /* Descale the transformed values 8 bits and output */
WiredHome 115:c9862fd0c689 512 dst[7] = BYTECLIP((v0 - v7) >> 8);
WiredHome 115:c9862fd0c689 513 dst[1] = BYTECLIP((v1 + v6) >> 8);
WiredHome 115:c9862fd0c689 514 dst[6] = BYTECLIP((v1 - v6) >> 8);
WiredHome 115:c9862fd0c689 515 dst[2] = BYTECLIP((v2 + v5) >> 8);
WiredHome 115:c9862fd0c689 516 dst[5] = BYTECLIP((v2 - v5) >> 8);
WiredHome 115:c9862fd0c689 517 dst[3] = BYTECLIP((v3 + v4) >> 8);
WiredHome 115:c9862fd0c689 518 dst[4] = BYTECLIP((v3 - v4) >> 8);
WiredHome 115:c9862fd0c689 519 dst += 8;
WiredHome 115:c9862fd0c689 520
WiredHome 115:c9862fd0c689 521 src += 8; /* Next row */
WiredHome 115:c9862fd0c689 522 }
WiredHome 115:c9862fd0c689 523 }
WiredHome 115:c9862fd0c689 524
WiredHome 115:c9862fd0c689 525
WiredHome 115:c9862fd0c689 526
WiredHome 115:c9862fd0c689 527
WiredHome 115:c9862fd0c689 528 /*-----------------------------------------------------------------------*/
WiredHome 115:c9862fd0c689 529 /* Load all blocks in the MCU into working buffer */
WiredHome 115:c9862fd0c689 530 /*-----------------------------------------------------------------------*/
WiredHome 115:c9862fd0c689 531
WiredHome 115:c9862fd0c689 532 JRESULT GraphicsDisplay::mcu_load (
WiredHome 115:c9862fd0c689 533 JDEC * jd /* Pointer to the decompressor object */
WiredHome 115:c9862fd0c689 534 )
WiredHome 115:c9862fd0c689 535 {
WiredHome 115:c9862fd0c689 536 int32_t *tmp = (int32_t *)jd->workbuf; /* Block working buffer for de-quantize and IDCT */
WiredHome 115:c9862fd0c689 537 uint16_t blk, nby, nbc, i, z, id, cmp;
WiredHome 115:c9862fd0c689 538 int16_t b, d, e;
WiredHome 115:c9862fd0c689 539 uint8_t *bp;
WiredHome 115:c9862fd0c689 540 const uint8_t *hb, *hd;
WiredHome 115:c9862fd0c689 541 const uint16_t *hc;
WiredHome 115:c9862fd0c689 542 const int32_t *dqf;
WiredHome 115:c9862fd0c689 543
WiredHome 118:34eb0b64fc61 544 INFO("mcu_load");
WiredHome 118:34eb0b64fc61 545 HexDump("JDEC", (uint8_t *)jd, sizeof(JDEC));
WiredHome 118:34eb0b64fc61 546
WiredHome 115:c9862fd0c689 547 nby = jd->msx * jd->msy; /* Number of Y blocks (1, 2 or 4) */
WiredHome 115:c9862fd0c689 548 nbc = 2; /* Number of C blocks (2) */
WiredHome 115:c9862fd0c689 549 bp = jd->mcubuf; /* Pointer to the first block */
WiredHome 115:c9862fd0c689 550
WiredHome 115:c9862fd0c689 551 for (blk = 0; blk < nby + nbc; blk++) {
WiredHome 115:c9862fd0c689 552 cmp = (blk < nby) ? 0 : blk - nby + 1; /* Component number 0:Y, 1:Cb, 2:Cr */
WiredHome 115:c9862fd0c689 553 id = cmp ? 1 : 0; /* Huffman table ID of the component */
WiredHome 115:c9862fd0c689 554
WiredHome 115:c9862fd0c689 555 /* Extract a DC element from input stream */
WiredHome 115:c9862fd0c689 556 hb = jd->huffbits[id][0]; /* Huffman table for the DC element */
WiredHome 115:c9862fd0c689 557 hc = jd->huffcode[id][0];
WiredHome 115:c9862fd0c689 558 hd = jd->huffdata[id][0];
WiredHome 115:c9862fd0c689 559 b = huffext(jd, hb, hc, hd); /* Extract a huffman coded data (bit length) */
WiredHome 115:c9862fd0c689 560 if (b < 0) return (JRESULT)(0 - b); /* Err: invalid code or input */
WiredHome 115:c9862fd0c689 561 d = jd->dcv[cmp]; /* DC value of previous block */
WiredHome 115:c9862fd0c689 562 if (b) { /* If there is any difference from previous block */
WiredHome 115:c9862fd0c689 563 e = bitext(jd, b); /* Extract data bits */
WiredHome 115:c9862fd0c689 564 if (e < 0) return (JRESULT)(0 - e); /* Err: input */
WiredHome 115:c9862fd0c689 565 b = 1 << (b - 1); /* MSB position */
WiredHome 115:c9862fd0c689 566 if (!(e & b)) e -= (b << 1) - 1; /* Restore sign if needed */
WiredHome 115:c9862fd0c689 567 d += e; /* Get current value */
WiredHome 115:c9862fd0c689 568 jd->dcv[cmp] = (int16_t)d; /* Save current DC value for next block */
WiredHome 115:c9862fd0c689 569 }
WiredHome 115:c9862fd0c689 570 dqf = jd->qttbl[jd->qtid[cmp]]; /* De-quantizer table ID for this component */
WiredHome 115:c9862fd0c689 571 tmp[0] = d * dqf[0] >> 8; /* De-quantize, apply scale factor of Arai algorithm and descale 8 bits */
WiredHome 115:c9862fd0c689 572
WiredHome 115:c9862fd0c689 573 /* Extract following 63 AC elements from input stream */
WiredHome 115:c9862fd0c689 574 for (i = 1; i < 64; i++) tmp[i] = 0; /* Clear rest of elements */
WiredHome 115:c9862fd0c689 575 hb = jd->huffbits[id][1]; /* Huffman table for the AC elements */
WiredHome 115:c9862fd0c689 576 hc = jd->huffcode[id][1];
WiredHome 115:c9862fd0c689 577 hd = jd->huffdata[id][1];
WiredHome 115:c9862fd0c689 578 i = 1; /* Top of the AC elements */
WiredHome 115:c9862fd0c689 579 do {
WiredHome 115:c9862fd0c689 580 b = huffext(jd, hb, hc, hd); /* Extract a huffman coded value (zero runs and bit length) */
WiredHome 115:c9862fd0c689 581 if (b == 0) break; /* EOB? */
WiredHome 115:c9862fd0c689 582 if (b < 0) return (JRESULT)(0 - b); /* Err: invalid code or input error */
WiredHome 115:c9862fd0c689 583 z = (uint16_t)b >> 4; /* Number of leading zero elements */
WiredHome 115:c9862fd0c689 584 if (z) {
WiredHome 115:c9862fd0c689 585 i += z; /* Skip zero elements */
WiredHome 115:c9862fd0c689 586 if (i >= 64) return JDR_FMT1; /* Too long zero run */
WiredHome 115:c9862fd0c689 587 }
WiredHome 115:c9862fd0c689 588 if (b &= 0x0F) { /* Bit length */
WiredHome 115:c9862fd0c689 589 d = bitext(jd, b); /* Extract data bits */
WiredHome 115:c9862fd0c689 590 if (d < 0) return (JRESULT)(0 - d); /* Err: input device */
WiredHome 115:c9862fd0c689 591 b = 1 << (b - 1); /* MSB position */
WiredHome 115:c9862fd0c689 592 if (!(d & b)) d -= (b << 1) - 1;/* Restore negative value if needed */
WiredHome 115:c9862fd0c689 593 z = ZIG(i); /* Zigzag-order to raster-order converted index */
WiredHome 115:c9862fd0c689 594 tmp[z] = d * dqf[z] >> 8; /* De-quantize, apply scale factor of Arai algorithm and descale 8 bits */
WiredHome 115:c9862fd0c689 595 }
WiredHome 115:c9862fd0c689 596 } while (++i < 64); /* Next AC element */
WiredHome 115:c9862fd0c689 597
WiredHome 115:c9862fd0c689 598 if (JD_USE_SCALE && jd->scale == 3)
WiredHome 115:c9862fd0c689 599 *bp = (*tmp / 256) + 128; /* If scale ratio is 1/8, IDCT can be ommited and only DC element is used */
WiredHome 115:c9862fd0c689 600 else
WiredHome 115:c9862fd0c689 601 block_idct(tmp, bp); /* Apply IDCT and store the block to the MCU buffer */
WiredHome 115:c9862fd0c689 602
WiredHome 115:c9862fd0c689 603 bp += 64; /* Next block */
WiredHome 115:c9862fd0c689 604 }
WiredHome 115:c9862fd0c689 605
WiredHome 115:c9862fd0c689 606 return JDR_OK; /* All blocks have been loaded successfully */
WiredHome 115:c9862fd0c689 607 }
WiredHome 115:c9862fd0c689 608
WiredHome 115:c9862fd0c689 609
WiredHome 115:c9862fd0c689 610
WiredHome 115:c9862fd0c689 611
WiredHome 115:c9862fd0c689 612 /*-----------------------------------------------------------------------*/
WiredHome 115:c9862fd0c689 613 /* Output an MCU: Convert YCrCb to RGB and output it in RGB form */
WiredHome 115:c9862fd0c689 614 /*-----------------------------------------------------------------------*/
WiredHome 115:c9862fd0c689 615
WiredHome 115:c9862fd0c689 616 JRESULT GraphicsDisplay::mcu_output (
WiredHome 115:c9862fd0c689 617 JDEC * jd, /* Pointer to the decompressor object */
WiredHome 115:c9862fd0c689 618 uint16_t (* outfunc)(JDEC * jd, void * stream, JRECT * rect), /* RGB output function */
WiredHome 115:c9862fd0c689 619 uint16_t x, /* MCU position in the image (left of the MCU) */
WiredHome 115:c9862fd0c689 620 uint16_t y /* MCU position in the image (top of the MCU) */
WiredHome 115:c9862fd0c689 621 )
WiredHome 115:c9862fd0c689 622 {
WiredHome 115:c9862fd0c689 623 const int16_t CVACC = (sizeof (int16_t) > 2) ? 1024 : 128;
WiredHome 115:c9862fd0c689 624 uint16_t ix, iy, mx, my, rx, ry;
WiredHome 115:c9862fd0c689 625 int16_t yy, cb, cr;
WiredHome 115:c9862fd0c689 626 uint8_t *py, *pc, *rgb24;
WiredHome 115:c9862fd0c689 627 JRECT rect;
WiredHome 115:c9862fd0c689 628
WiredHome 118:34eb0b64fc61 629 INFO("mcu_output(%p,%p,%d,%d)", jd, outfunc, x, y);
WiredHome 118:34eb0b64fc61 630 HexDump("JDEC", (uint8_t *)jd, sizeof(JDEC));
WiredHome 118:34eb0b64fc61 631
WiredHome 115:c9862fd0c689 632 mx = jd->msx * 8; my = jd->msy * 8; /* MCU size (pixel) */
WiredHome 115:c9862fd0c689 633 rx = (x + mx <= jd->width) ? mx : jd->width - x; /* Output rectangular size (it may be clipped at right/bottom end) */
WiredHome 115:c9862fd0c689 634 ry = (y + my <= jd->height) ? my : jd->height - y;
WiredHome 115:c9862fd0c689 635 if (JD_USE_SCALE) {
WiredHome 115:c9862fd0c689 636 rx >>= jd->scale; ry >>= jd->scale;
WiredHome 115:c9862fd0c689 637 if (!rx || !ry) return JDR_OK; /* Skip this MCU if all pixel is to be rounded off */
WiredHome 115:c9862fd0c689 638 x >>= jd->scale; y >>= jd->scale;
WiredHome 115:c9862fd0c689 639 }
WiredHome 115:c9862fd0c689 640 rect.left = x; rect.right = x + rx - 1; /* Rectangular area in the frame buffer */
WiredHome 115:c9862fd0c689 641 rect.top = y; rect.bottom = y + ry - 1;
WiredHome 115:c9862fd0c689 642
WiredHome 115:c9862fd0c689 643
WiredHome 115:c9862fd0c689 644 if (!JD_USE_SCALE || jd->scale != 3) { /* Not for 1/8 scaling */
WiredHome 115:c9862fd0c689 645
WiredHome 115:c9862fd0c689 646 /* Build an RGB MCU from discrete comopnents */
WiredHome 115:c9862fd0c689 647 rgb24 = (uint8_t *)jd->workbuf;
WiredHome 115:c9862fd0c689 648 for (iy = 0; iy < my; iy++) {
WiredHome 115:c9862fd0c689 649 pc = jd->mcubuf;
WiredHome 115:c9862fd0c689 650 py = pc + iy * 8;
WiredHome 115:c9862fd0c689 651 if (my == 16) { /* Double block height? */
WiredHome 115:c9862fd0c689 652 pc += 64 * 4 + (iy >> 1) * 8;
WiredHome 115:c9862fd0c689 653 if (iy >= 8) py += 64;
WiredHome 115:c9862fd0c689 654 } else { /* Single block height */
WiredHome 115:c9862fd0c689 655 pc += mx * 8 + iy * 8;
WiredHome 115:c9862fd0c689 656 }
WiredHome 115:c9862fd0c689 657 for (ix = 0; ix < mx; ix++) {
WiredHome 115:c9862fd0c689 658 cb = pc[0] - 128; /* Get Cb/Cr component and restore right level */
WiredHome 115:c9862fd0c689 659 cr = pc[64] - 128;
WiredHome 115:c9862fd0c689 660 if (mx == 16) { /* Double block width? */
WiredHome 115:c9862fd0c689 661 if (ix == 8) py += 64 - 8; /* Jump to next block if double block heigt */
WiredHome 115:c9862fd0c689 662 pc += ix & 1; /* Increase chroma pointer every two pixels */
WiredHome 115:c9862fd0c689 663 } else { /* Single block width */
WiredHome 115:c9862fd0c689 664 pc++; /* Increase chroma pointer every pixel */
WiredHome 115:c9862fd0c689 665 }
WiredHome 115:c9862fd0c689 666 yy = *py++; /* Get Y component */
WiredHome 115:c9862fd0c689 667
WiredHome 115:c9862fd0c689 668 /* Convert YCbCr to RGB */
WiredHome 115:c9862fd0c689 669 *rgb24++ = /* R */ BYTECLIP(yy + ((int16_t)(1.402 * CVACC) * cr) / CVACC);
WiredHome 115:c9862fd0c689 670 *rgb24++ = /* G */ BYTECLIP(yy - ((int16_t)(0.344 * CVACC) * cb + (int16_t)(0.714 * CVACC) * cr) / CVACC);
WiredHome 115:c9862fd0c689 671 *rgb24++ = /* B */ BYTECLIP(yy + ((int16_t)(1.772 * CVACC) * cb) / CVACC);
WiredHome 115:c9862fd0c689 672 }
WiredHome 115:c9862fd0c689 673 }
WiredHome 115:c9862fd0c689 674
WiredHome 115:c9862fd0c689 675 /* Descale the MCU rectangular if needed */
WiredHome 115:c9862fd0c689 676 if (JD_USE_SCALE && jd->scale) {
WiredHome 115:c9862fd0c689 677 uint16_t x, y, r, g, b, s, w, a;
WiredHome 115:c9862fd0c689 678 uint8_t *op;
WiredHome 115:c9862fd0c689 679
WiredHome 115:c9862fd0c689 680 /* Get averaged RGB value of each square correcponds to a pixel */
WiredHome 115:c9862fd0c689 681 s = jd->scale * 2; /* Bumber of shifts for averaging */
WiredHome 115:c9862fd0c689 682 w = 1 << jd->scale; /* Width of square */
WiredHome 115:c9862fd0c689 683 a = (mx - w) * 3; /* Bytes to skip for next line in the square */
WiredHome 115:c9862fd0c689 684 op = (uint8_t *)jd->workbuf;
WiredHome 115:c9862fd0c689 685 for (iy = 0; iy < my; iy += w) {
WiredHome 115:c9862fd0c689 686 for (ix = 0; ix < mx; ix += w) {
WiredHome 115:c9862fd0c689 687 rgb24 = (uint8_t *)jd->workbuf + (iy * mx + ix) * 3;
WiredHome 115:c9862fd0c689 688 r = g = b = 0;
WiredHome 115:c9862fd0c689 689 for (y = 0; y < w; y++) { /* Accumulate RGB value in the square */
WiredHome 115:c9862fd0c689 690 for (x = 0; x < w; x++) {
WiredHome 115:c9862fd0c689 691 r += *rgb24++;
WiredHome 115:c9862fd0c689 692 g += *rgb24++;
WiredHome 115:c9862fd0c689 693 b += *rgb24++;
WiredHome 115:c9862fd0c689 694 }
WiredHome 115:c9862fd0c689 695 rgb24 += a;
WiredHome 115:c9862fd0c689 696 } /* Put the averaged RGB value as a pixel */
WiredHome 115:c9862fd0c689 697 *op++ = (uint8_t)(r >> s);
WiredHome 115:c9862fd0c689 698 *op++ = (uint8_t)(g >> s);
WiredHome 115:c9862fd0c689 699 *op++ = (uint8_t)(b >> s);
WiredHome 115:c9862fd0c689 700 }
WiredHome 115:c9862fd0c689 701 }
WiredHome 115:c9862fd0c689 702 }
WiredHome 115:c9862fd0c689 703
WiredHome 115:c9862fd0c689 704 } else { /* For only 1/8 scaling (left-top pixel in each block are the DC value of the block) */
WiredHome 115:c9862fd0c689 705
WiredHome 115:c9862fd0c689 706 /* Build a 1/8 descaled RGB MCU from discrete comopnents */
WiredHome 115:c9862fd0c689 707 rgb24 = (uint8_t *)jd->workbuf;
WiredHome 115:c9862fd0c689 708 pc = jd->mcubuf + mx * my;
WiredHome 115:c9862fd0c689 709 cb = pc[0] - 128; /* Get Cb/Cr component and restore right level */
WiredHome 115:c9862fd0c689 710 cr = pc[64] - 128;
WiredHome 115:c9862fd0c689 711 for (iy = 0; iy < my; iy += 8) {
WiredHome 115:c9862fd0c689 712 py = jd->mcubuf;
WiredHome 115:c9862fd0c689 713 if (iy == 8) py += 64 * 2;
WiredHome 115:c9862fd0c689 714 for (ix = 0; ix < mx; ix += 8) {
WiredHome 115:c9862fd0c689 715 yy = *py; /* Get Y component */
WiredHome 115:c9862fd0c689 716 py += 64;
WiredHome 115:c9862fd0c689 717
WiredHome 115:c9862fd0c689 718 /* Convert YCbCr to RGB */
WiredHome 115:c9862fd0c689 719 *rgb24++ = /* R */ BYTECLIP(yy + ((int16_t)(1.402 * CVACC) * cr / CVACC));
WiredHome 115:c9862fd0c689 720 *rgb24++ = /* G */ BYTECLIP(yy - ((int16_t)(0.344 * CVACC) * cb + (int16_t)(0.714 * CVACC) * cr) / CVACC);
WiredHome 115:c9862fd0c689 721 *rgb24++ = /* B */ BYTECLIP(yy + ((int16_t)(1.772 * CVACC) * cb / CVACC));
WiredHome 115:c9862fd0c689 722 }
WiredHome 115:c9862fd0c689 723 }
WiredHome 115:c9862fd0c689 724 }
WiredHome 115:c9862fd0c689 725
WiredHome 115:c9862fd0c689 726 /* Squeeze up pixel table if a part of MCU is to be truncated */
WiredHome 115:c9862fd0c689 727 mx >>= jd->scale;
WiredHome 115:c9862fd0c689 728 if (rx < mx) {
WiredHome 115:c9862fd0c689 729 uint8_t *s, *d;
WiredHome 115:c9862fd0c689 730 uint16_t x, y;
WiredHome 115:c9862fd0c689 731
WiredHome 115:c9862fd0c689 732 s = d = (uint8_t *)jd->workbuf;
WiredHome 115:c9862fd0c689 733 for (y = 0; y < ry; y++) {
WiredHome 115:c9862fd0c689 734 for (x = 0; x < rx; x++) { /* Copy effective pixels */
WiredHome 115:c9862fd0c689 735 *d++ = *s++;
WiredHome 115:c9862fd0c689 736 *d++ = *s++;
WiredHome 115:c9862fd0c689 737 *d++ = *s++;
WiredHome 115:c9862fd0c689 738 }
WiredHome 115:c9862fd0c689 739 s += (mx - rx) * 3; /* Skip truncated pixels */
WiredHome 115:c9862fd0c689 740 }
WiredHome 115:c9862fd0c689 741 }
WiredHome 115:c9862fd0c689 742
WiredHome 115:c9862fd0c689 743 /* Convert RGB888 to RGB565 if needed */
WiredHome 115:c9862fd0c689 744 if (JD_FORMAT == 1) {
WiredHome 115:c9862fd0c689 745 uint8_t *s = (uint8_t *)jd->workbuf;
WiredHome 115:c9862fd0c689 746 uint16_t w, *d = (uint16_t *)s;
WiredHome 115:c9862fd0c689 747 uint16_t n = rx * ry;
WiredHome 115:c9862fd0c689 748
WiredHome 115:c9862fd0c689 749 do {
WiredHome 115:c9862fd0c689 750 w = (*s++ & 0xF8) << 8; /* RRRRR----------- */
WiredHome 115:c9862fd0c689 751 w |= (*s++ & 0xFC) << 3; /* -----GGGGGG----- */
WiredHome 115:c9862fd0c689 752 w |= *s++ >> 3; /* -----------BBBBB */
WiredHome 115:c9862fd0c689 753 *d++ = w;
WiredHome 115:c9862fd0c689 754 } while (--n);
WiredHome 115:c9862fd0c689 755 }
WiredHome 115:c9862fd0c689 756
WiredHome 115:c9862fd0c689 757 /* Output the RGB rectangular */
WiredHome 119:d129b798f82f 758 INFO("call outfunc");
WiredHome 115:c9862fd0c689 759 if (outfunc)
WiredHome 115:c9862fd0c689 760 return outfunc(jd, jd->workbuf, &rect) ? JDR_OK : JDR_INTR;
WiredHome 115:c9862fd0c689 761 else
WiredHome 115:c9862fd0c689 762 return privOutFunc(jd, jd->workbuf, &rect) ? JDR_OK : JDR_INTR;
WiredHome 115:c9862fd0c689 763 }
WiredHome 115:c9862fd0c689 764
WiredHome 115:c9862fd0c689 765
WiredHome 115:c9862fd0c689 766
WiredHome 115:c9862fd0c689 767
WiredHome 115:c9862fd0c689 768 /*-----------------------------------------------------------------------*/
WiredHome 115:c9862fd0c689 769 /* Process restart interval */
WiredHome 115:c9862fd0c689 770 /*-----------------------------------------------------------------------*/
WiredHome 115:c9862fd0c689 771
WiredHome 115:c9862fd0c689 772 JRESULT GraphicsDisplay::restart (
WiredHome 115:c9862fd0c689 773 JDEC * jd, /* Pointer to the decompressor object */
WiredHome 115:c9862fd0c689 774 uint16_t rstn /* Expected restert sequense number */
WiredHome 115:c9862fd0c689 775 )
WiredHome 115:c9862fd0c689 776 {
WiredHome 115:c9862fd0c689 777 uint16_t i, dc;
WiredHome 115:c9862fd0c689 778 uint16_t d;
WiredHome 115:c9862fd0c689 779 uint8_t *dp;
WiredHome 118:34eb0b64fc61 780
WiredHome 116:43e5bd2d7302 781 INFO("restart(%p,%d)", jd, rstn);
WiredHome 115:c9862fd0c689 782
WiredHome 115:c9862fd0c689 783 /* Discard padding bits and get two bytes from the input stream */
WiredHome 115:c9862fd0c689 784 dp = jd->dptr; dc = jd->dctr;
WiredHome 115:c9862fd0c689 785 d = 0;
WiredHome 115:c9862fd0c689 786 for (i = 0; i < 2; i++) {
WiredHome 115:c9862fd0c689 787 if (!dc) { /* No input data is available, re-fill input buffer */
WiredHome 115:c9862fd0c689 788 dp = jd->inbuf;
WiredHome 115:c9862fd0c689 789 dc = getJpegData(jd, dp, JD_SZBUF);
WiredHome 115:c9862fd0c689 790 if (!dc) return JDR_INP;
WiredHome 115:c9862fd0c689 791 } else {
WiredHome 115:c9862fd0c689 792 dp++;
WiredHome 115:c9862fd0c689 793 }
WiredHome 115:c9862fd0c689 794 dc--;
WiredHome 115:c9862fd0c689 795 d = (d << 8) | *dp; /* Get a byte */
WiredHome 115:c9862fd0c689 796 }
WiredHome 115:c9862fd0c689 797 jd->dptr = dp; jd->dctr = dc; jd->dmsk = 0;
WiredHome 115:c9862fd0c689 798
WiredHome 115:c9862fd0c689 799 /* Check the marker */
WiredHome 115:c9862fd0c689 800 if ((d & 0xFFD8) != 0xFFD0 || (d & 7) != (rstn & 7))
WiredHome 115:c9862fd0c689 801 return JDR_FMT1; /* Err: expected RSTn marker is not detected (may be collapted data) */
WiredHome 115:c9862fd0c689 802
WiredHome 115:c9862fd0c689 803 /* Reset DC offset */
WiredHome 115:c9862fd0c689 804 jd->dcv[2] = jd->dcv[1] = jd->dcv[0] = 0;
WiredHome 115:c9862fd0c689 805
WiredHome 115:c9862fd0c689 806 return JDR_OK;
WiredHome 115:c9862fd0c689 807 }
WiredHome 115:c9862fd0c689 808
WiredHome 115:c9862fd0c689 809
WiredHome 115:c9862fd0c689 810
WiredHome 115:c9862fd0c689 811
WiredHome 115:c9862fd0c689 812 /*-----------------------------------------------------------------------*/
WiredHome 115:c9862fd0c689 813 /* Analyze the JPEG image and Initialize decompressor object */
WiredHome 115:c9862fd0c689 814 /*-----------------------------------------------------------------------*/
WiredHome 115:c9862fd0c689 815
WiredHome 115:c9862fd0c689 816 #define LDB_WORD(ptr) (uint16_t)(((uint16_t)*((uint8_t *)(ptr))<<8)|(uint16_t)*(uint8_t *)((ptr)+1))
WiredHome 115:c9862fd0c689 817
WiredHome 115:c9862fd0c689 818 uint16_t GraphicsDisplay::privInFunc(JDEC * jd, uint8_t * buff, uint16_t ndata)
WiredHome 115:c9862fd0c689 819 {
WiredHome 120:be2aaa3adf72 820 //INFO("Read in %p count %d", buff, ndata);
WiredHome 115:c9862fd0c689 821 if (buff) {
WiredHome 115:c9862fd0c689 822 size_t n = fread(buff, 1, ndata, (FILE *)jd->device);
WiredHome 115:c9862fd0c689 823 INFO("fread returned %d of %d", n, ndata);
WiredHome 115:c9862fd0c689 824 HexDump("buf", buff, (ndata > 32) ? 32 : ndata);
WiredHome 115:c9862fd0c689 825 return n == (size_t)-1 ? 0 : n;
WiredHome 115:c9862fd0c689 826 } else {
WiredHome 115:c9862fd0c689 827 off_t t = fseek((FILE *)jd->device, ndata, SEEK_CUR);
WiredHome 115:c9862fd0c689 828 INFO("Seek returned %d", t);
WiredHome 115:c9862fd0c689 829 return t == (off_t)-1 ? 0 : ndata;
WiredHome 115:c9862fd0c689 830 }
WiredHome 115:c9862fd0c689 831 }
WiredHome 115:c9862fd0c689 832
WiredHome 115:c9862fd0c689 833 uint16_t GraphicsDisplay::getJpegData(JDEC * jd, uint8_t * buff, uint16_t ndata)
WiredHome 115:c9862fd0c689 834 {
WiredHome 120:be2aaa3adf72 835 //INFO("getJpegData(%p, %p, %d)", jd, buff, ndata);
WiredHome 115:c9862fd0c689 836 if (jd->infunc)
WiredHome 115:c9862fd0c689 837 return jd->infunc(jd, buff, ndata);
WiredHome 115:c9862fd0c689 838 else
WiredHome 115:c9862fd0c689 839 return privInFunc(jd, buff, ndata);
WiredHome 115:c9862fd0c689 840 }
WiredHome 115:c9862fd0c689 841
WiredHome 136:224e03d5c31f 842 // RGB565 if JD_FORMAT == 1
WiredHome 136:224e03d5c31f 843 // RGB888 if JD_FORMAT == 0
WiredHome 115:c9862fd0c689 844 uint16_t GraphicsDisplay::privOutFunc(JDEC * jd, void * bitmap, JRECT * rect)
WiredHome 115:c9862fd0c689 845 {
WiredHome 115:c9862fd0c689 846 int x0 = rect->left;
WiredHome 115:c9862fd0c689 847 int x1 = rect->right;
WiredHome 115:c9862fd0c689 848 int y0 = rect->top;
WiredHome 115:c9862fd0c689 849 int y1 = rect->bottom;
WiredHome 115:c9862fd0c689 850
WiredHome 115:c9862fd0c689 851 INFO("privOutFunc: (%d,%d)-(%d,%d) : (%d,%d)", x0,y0, x1,y1, width(), height());
WiredHome 115:c9862fd0c689 852 if (y0 >= height() || x0 >= width())
WiredHome 136:224e03d5c31f 853 return 1; // off the right || bottom of screen
WiredHome 136:224e03d5c31f 854 if (x1 > width()-1) x1 = width() - 1; // clip to width
WiredHome 136:224e03d5c31f 855 if (y1 > height()-1) y1 = height() - 1; // clip to height
WiredHome 136:224e03d5c31f 856
WiredHome 115:c9862fd0c689 857 int w = x1 - x0 + 1;
WiredHome 136:224e03d5c31f 858
WiredHome 136:224e03d5c31f 859 #if 1
WiredHome 136:224e03d5c31f 860 uint32_t pixelCount = (1 + (y1-y0)) * (1+x1-x0);
WiredHome 136:224e03d5c31f 861 #if JD_FORMAT == 0
WiredHome 136:224e03d5c31f 862 uint8_t *s = (uint8_t *)bitmap;
WiredHome 136:224e03d5c31f 863 uint16_t rgb565, *d = (uint16_t *)s;
WiredHome 136:224e03d5c31f 864 uint32_t pCount = pixelCount;
WiredHome 136:224e03d5c31f 865
WiredHome 136:224e03d5c31f 866 do {
WiredHome 136:224e03d5c31f 867 rgb565 = (*s++ & 0xF8) << 8; /* RRRRR----------- */
WiredHome 136:224e03d5c31f 868 rgb565 |= (*s++ & 0xFC) << 3; /* -----GGGGGG----- */
WiredHome 136:224e03d5c31f 869 rgb565 |= *s++ >> 3; /* -----------BBBBB */
WiredHome 136:224e03d5c31f 870 *d++ = rgb565;
WiredHome 136:224e03d5c31f 871 } while (--pCount);
WiredHome 136:224e03d5c31f 872 #endif
WiredHome 136:224e03d5c31f 873 //
WiredHome 136:224e03d5c31f 874 window(x0+img_x, y0+img_y, w, y1 - y0 + 2);
WiredHome 136:224e03d5c31f 875 uint16_t *src = (uint16_t *)bitmap; // pointer to RGB565 format
WiredHome 136:224e03d5c31f 876 pixelStream(src, pixelCount, x0+img_x, y0+img_y);
WiredHome 136:224e03d5c31f 877 window();
WiredHome 136:224e03d5c31f 878 #else
WiredHome 115:c9862fd0c689 879 for (int y= y0; y <= y1; y++) {
WiredHome 136:224e03d5c31f 880 SetGraphicsCursor(x0+img_x, y+img_y);
WiredHome 115:c9862fd0c689 881 _StartGraphicsStream();
WiredHome 115:c9862fd0c689 882 #if JD_FORMAT == 1
WiredHome 115:c9862fd0c689 883 uint16_t *p = src + w * (y - y0);
WiredHome 115:c9862fd0c689 884 #else
WiredHome 115:c9862fd0c689 885 uint8_t *p = src + 3 * (w * (y - y0));
WiredHome 115:c9862fd0c689 886 #endif
WiredHome 115:c9862fd0c689 887 for (int x=x0; x <= x1; x++) {
WiredHome 115:c9862fd0c689 888 #if JD_FORMAT == 1
WiredHome 115:c9862fd0c689 889 _putp(*p++);
WiredHome 115:c9862fd0c689 890 #else
WiredHome 115:c9862fd0c689 891 _putp(RGB(*p, *(p+1), *(p+2)));
WiredHome 115:c9862fd0c689 892 p += 3;
WiredHome 115:c9862fd0c689 893 #endif
WiredHome 115:c9862fd0c689 894 }
WiredHome 115:c9862fd0c689 895 _EndGraphicsStream();
WiredHome 115:c9862fd0c689 896 }
WiredHome 136:224e03d5c31f 897 #endif
WiredHome 115:c9862fd0c689 898 return 1;
WiredHome 115:c9862fd0c689 899 }
WiredHome 115:c9862fd0c689 900
WiredHome 115:c9862fd0c689 901 JRESULT GraphicsDisplay::jd_prepare (
WiredHome 115:c9862fd0c689 902 JDEC * jd, /* Blank decompressor object */
WiredHome 115:c9862fd0c689 903 uint16_t (*infunc)(JDEC *, uint8_t *, uint16_t), /* JPEG strem input function */
WiredHome 115:c9862fd0c689 904 void* pool, /* Working buffer for the decompression session */
WiredHome 115:c9862fd0c689 905 uint16_t sz_pool, /* Size of working buffer */
WiredHome 115:c9862fd0c689 906 void* dev /* I/O device identifier for the session */
WiredHome 115:c9862fd0c689 907 )
WiredHome 115:c9862fd0c689 908 {
WiredHome 115:c9862fd0c689 909 uint8_t *seg, b;
WiredHome 115:c9862fd0c689 910 uint16_t marker;
WiredHome 115:c9862fd0c689 911 uint32_t ofs;
WiredHome 115:c9862fd0c689 912 uint16_t n, i, j, len;
WiredHome 115:c9862fd0c689 913 JRESULT rc;
WiredHome 115:c9862fd0c689 914
WiredHome 120:be2aaa3adf72 915 INFO("jd_prepare(%p,%p,%p,%d,%p)", jd, infunc, pool, sz_pool, dev);
WiredHome 121:6bc4911f5e55 916 HexDump("JDEC 1", (uint8_t *)jd, sizeof(JDEC));
WiredHome 118:34eb0b64fc61 917
WiredHome 115:c9862fd0c689 918 if (!pool) {
WiredHome 115:c9862fd0c689 919 ERR("JDR_PAR");
WiredHome 115:c9862fd0c689 920 return JDR_PAR;
WiredHome 115:c9862fd0c689 921 }
WiredHome 115:c9862fd0c689 922
WiredHome 120:be2aaa3adf72 923 //INFO("pool is at %p", pool);
WiredHome 115:c9862fd0c689 924 jd->pool = pool; /* Work memroy */
WiredHome 115:c9862fd0c689 925 jd->sz_pool = sz_pool; /* Size of given work memory */
WiredHome 115:c9862fd0c689 926 jd->infunc = infunc; /* Stream input function */
WiredHome 115:c9862fd0c689 927 jd->device = dev; /* I/O device identifier */
WiredHome 115:c9862fd0c689 928 jd->nrst = 0; /* No restart interval (default) */
WiredHome 115:c9862fd0c689 929
WiredHome 115:c9862fd0c689 930 for (i = 0; i < 2; i++) { /* Nulls pointers */
WiredHome 115:c9862fd0c689 931 for (j = 0; j < 2; j++) {
WiredHome 115:c9862fd0c689 932 jd->huffbits[i][j] = 0;
WiredHome 115:c9862fd0c689 933 jd->huffcode[i][j] = 0;
WiredHome 115:c9862fd0c689 934 jd->huffdata[i][j] = 0;
WiredHome 115:c9862fd0c689 935 }
WiredHome 115:c9862fd0c689 936 }
WiredHome 115:c9862fd0c689 937 for (i = 0; i < 4; i++) jd->qttbl[i] = 0;
WiredHome 121:6bc4911f5e55 938 HexDump("JDEC 2", (uint8_t *)jd, sizeof(JDEC));
WiredHome 115:c9862fd0c689 939
WiredHome 115:c9862fd0c689 940 jd->inbuf = seg = (uint8_t *)alloc_pool(jd, JD_SZBUF); /* Allocate stream input buffer */
WiredHome 115:c9862fd0c689 941 if (!seg) {
WiredHome 115:c9862fd0c689 942 ERR("JDR_MEM1");
WiredHome 115:c9862fd0c689 943 return JDR_MEM1;
WiredHome 115:c9862fd0c689 944 }
WiredHome 121:6bc4911f5e55 945 HexDump("JDEC 3", (uint8_t *)jd, sizeof(JDEC));
WiredHome 115:c9862fd0c689 946
WiredHome 115:c9862fd0c689 947 if (getJpegData(jd, seg, 2) != 2) {
WiredHome 115:c9862fd0c689 948 ERR("JDR_INP");
WiredHome 115:c9862fd0c689 949 return JDR_INP;/* Check SOI marker */
WiredHome 115:c9862fd0c689 950 }
WiredHome 120:be2aaa3adf72 951 INFO("Checkpoint");
WiredHome 115:c9862fd0c689 952 HexDump("SOI marker", seg, 2);
WiredHome 115:c9862fd0c689 953 if (LDB_WORD(seg) != 0xFFD8) {
WiredHome 115:c9862fd0c689 954 ERR("JDR_FMT1");
WiredHome 115:c9862fd0c689 955 return JDR_FMT1; /* Err: SOI is not detected */
WiredHome 115:c9862fd0c689 956 }
WiredHome 115:c9862fd0c689 957 ofs = 2;
WiredHome 115:c9862fd0c689 958
WiredHome 115:c9862fd0c689 959 for (;;) {
WiredHome 115:c9862fd0c689 960 /* Get a JPEG marker */
WiredHome 115:c9862fd0c689 961 if (getJpegData(jd, seg, 4) != 4) {
WiredHome 115:c9862fd0c689 962 ERR("JDR_INP");
WiredHome 115:c9862fd0c689 963 return JDR_INP;
WiredHome 115:c9862fd0c689 964 }
WiredHome 115:c9862fd0c689 965 marker = LDB_WORD(seg); /* Marker */
WiredHome 115:c9862fd0c689 966 len = LDB_WORD(seg + 2); /* Length field */
WiredHome 115:c9862fd0c689 967 if (len <= 2 || (marker >> 8) != 0xFF) {
WiredHome 115:c9862fd0c689 968 ERR("JDR_FMT1");
WiredHome 115:c9862fd0c689 969 return JDR_FMT1;
WiredHome 115:c9862fd0c689 970 }
WiredHome 115:c9862fd0c689 971 len -= 2; /* Content size excluding length field */
WiredHome 115:c9862fd0c689 972 ofs += 4 + len; /* Number of bytes loaded */
WiredHome 115:c9862fd0c689 973
WiredHome 115:c9862fd0c689 974 switch (marker & 0xFF) {
WiredHome 115:c9862fd0c689 975 case 0xC0: /* SOF0 (baseline JPEG) */
WiredHome 115:c9862fd0c689 976 /* Load segment data */
WiredHome 115:c9862fd0c689 977 if (len > JD_SZBUF) {
WiredHome 115:c9862fd0c689 978 ERR("JDR_MEM2");
WiredHome 115:c9862fd0c689 979 return JDR_MEM2;
WiredHome 115:c9862fd0c689 980 }
WiredHome 115:c9862fd0c689 981 if (getJpegData(jd, seg, len) != len) {
WiredHome 115:c9862fd0c689 982 ERR("JDR_INP");
WiredHome 115:c9862fd0c689 983 return JDR_INP;
WiredHome 115:c9862fd0c689 984 }
WiredHome 115:c9862fd0c689 985
WiredHome 115:c9862fd0c689 986 jd->width = LDB_WORD(seg+3); /* Image width in unit of pixel */
WiredHome 115:c9862fd0c689 987 jd->height = LDB_WORD(seg+1); /* Image height in unit of pixel */
WiredHome 115:c9862fd0c689 988 INFO("Image size(%d,%d)", jd->width, jd->height);
WiredHome 115:c9862fd0c689 989
WiredHome 115:c9862fd0c689 990 if (seg[5] != 3) {
WiredHome 115:c9862fd0c689 991 ERR("JDR_FMT3");
WiredHome 115:c9862fd0c689 992 return JDR_FMT3; /* Err: Supports only Y/Cb/Cr format */
WiredHome 115:c9862fd0c689 993 }
WiredHome 115:c9862fd0c689 994
WiredHome 115:c9862fd0c689 995 /* Check three image components */
WiredHome 115:c9862fd0c689 996 for (i = 0; i < 3; i++) {
WiredHome 115:c9862fd0c689 997 b = seg[7 + 3 * i]; /* Get sampling factor */
WiredHome 115:c9862fd0c689 998 if (!i) { /* Y component */
WiredHome 115:c9862fd0c689 999 if (b != 0x11 && b != 0x22 && b != 0x21) {/* Check sampling factor */
WiredHome 115:c9862fd0c689 1000 ERR("JDR_FMT3");
WiredHome 115:c9862fd0c689 1001 return JDR_FMT3; /* Err: Supports only 4:4:4, 4:2:0 or 4:2:2 */
WiredHome 115:c9862fd0c689 1002 }
WiredHome 115:c9862fd0c689 1003 jd->msx = b >> 4; jd->msy = b & 15; /* Size of MCU [blocks] */
WiredHome 115:c9862fd0c689 1004 } else { /* Cb/Cr component */
WiredHome 115:c9862fd0c689 1005 if (b != 0x11) {
WiredHome 115:c9862fd0c689 1006 ERR("JDR_FMT3");
WiredHome 115:c9862fd0c689 1007 return JDR_FMT3; /* Err: Sampling factor of Cr/Cb must be 1 */
WiredHome 115:c9862fd0c689 1008 }
WiredHome 115:c9862fd0c689 1009 }
WiredHome 115:c9862fd0c689 1010 b = seg[8 + 3 * i]; /* Get dequantizer table ID for this component */
WiredHome 115:c9862fd0c689 1011 if (b > 3) {
WiredHome 115:c9862fd0c689 1012 ERR("JDR_FMT3");
WiredHome 115:c9862fd0c689 1013 return JDR_FMT3; /* Err: Invalid ID */
WiredHome 115:c9862fd0c689 1014 }
WiredHome 115:c9862fd0c689 1015 jd->qtid[i] = b;
WiredHome 115:c9862fd0c689 1016 }
WiredHome 115:c9862fd0c689 1017 break;
WiredHome 115:c9862fd0c689 1018
WiredHome 115:c9862fd0c689 1019 case 0xDD: /* DRI */
WiredHome 115:c9862fd0c689 1020 /* Load segment data */
WiredHome 115:c9862fd0c689 1021 if (len > JD_SZBUF) {
WiredHome 115:c9862fd0c689 1022 ERR("JDR_MEM2");
WiredHome 115:c9862fd0c689 1023 return JDR_MEM2;
WiredHome 115:c9862fd0c689 1024 }
WiredHome 115:c9862fd0c689 1025 if (getJpegData(jd, seg, len) != len) {
WiredHome 115:c9862fd0c689 1026 ERR("JDR_INP");
WiredHome 115:c9862fd0c689 1027 return JDR_INP;
WiredHome 115:c9862fd0c689 1028 }
WiredHome 115:c9862fd0c689 1029
WiredHome 115:c9862fd0c689 1030 /* Get restart interval (MCUs) */
WiredHome 115:c9862fd0c689 1031 jd->nrst = LDB_WORD(seg);
WiredHome 115:c9862fd0c689 1032 break;
WiredHome 115:c9862fd0c689 1033
WiredHome 115:c9862fd0c689 1034 case 0xC4: /* DHT */
WiredHome 115:c9862fd0c689 1035 /* Load segment data */
WiredHome 115:c9862fd0c689 1036 if (len > JD_SZBUF) {
WiredHome 115:c9862fd0c689 1037 ERR("JDR_MEM2");
WiredHome 115:c9862fd0c689 1038 return JDR_MEM2;
WiredHome 115:c9862fd0c689 1039 }
WiredHome 115:c9862fd0c689 1040 if (getJpegData(jd, seg, len) != len) {
WiredHome 115:c9862fd0c689 1041 ERR("JDR_INP");
WiredHome 115:c9862fd0c689 1042 return JDR_INP;
WiredHome 115:c9862fd0c689 1043 }
WiredHome 115:c9862fd0c689 1044
WiredHome 115:c9862fd0c689 1045 /* Create huffman tables */
WiredHome 115:c9862fd0c689 1046 INFO("next - create_huffman_tbl()");
WiredHome 115:c9862fd0c689 1047 rc = (JRESULT)create_huffman_tbl(jd, seg, len);
WiredHome 115:c9862fd0c689 1048 if (rc) {
WiredHome 115:c9862fd0c689 1049 ERR("rc = %d", rc);
WiredHome 115:c9862fd0c689 1050 return rc;
WiredHome 115:c9862fd0c689 1051 }
WiredHome 115:c9862fd0c689 1052 break;
WiredHome 115:c9862fd0c689 1053
WiredHome 115:c9862fd0c689 1054 case 0xDB: /* DQT */
WiredHome 115:c9862fd0c689 1055 /* Load segment data */
WiredHome 115:c9862fd0c689 1056 if (len > JD_SZBUF) {
WiredHome 115:c9862fd0c689 1057 ERR("JDR_MEM2");
WiredHome 115:c9862fd0c689 1058 return JDR_MEM2;
WiredHome 115:c9862fd0c689 1059 }
WiredHome 115:c9862fd0c689 1060 if (getJpegData(jd, seg, len) != len) {
WiredHome 115:c9862fd0c689 1061 ERR("JDR_INP");
WiredHome 115:c9862fd0c689 1062 return JDR_INP;
WiredHome 115:c9862fd0c689 1063 }
WiredHome 115:c9862fd0c689 1064
WiredHome 115:c9862fd0c689 1065 /* Create de-quantizer tables */
WiredHome 115:c9862fd0c689 1066 rc = (JRESULT)create_qt_tbl(jd, seg, len);
WiredHome 115:c9862fd0c689 1067 if (rc) {
WiredHome 115:c9862fd0c689 1068 ERR("rc = %d", rc);
WiredHome 115:c9862fd0c689 1069 return rc;
WiredHome 115:c9862fd0c689 1070 }
WiredHome 115:c9862fd0c689 1071 break;
WiredHome 115:c9862fd0c689 1072
WiredHome 115:c9862fd0c689 1073 case 0xDA: /* SOS */
WiredHome 115:c9862fd0c689 1074 /* Load segment data */
WiredHome 115:c9862fd0c689 1075 if (len > JD_SZBUF) {
WiredHome 115:c9862fd0c689 1076 ERR("JDR_MEM2");
WiredHome 115:c9862fd0c689 1077 return JDR_MEM2;
WiredHome 115:c9862fd0c689 1078 }
WiredHome 115:c9862fd0c689 1079 if (getJpegData(jd, seg, len) != len) {
WiredHome 115:c9862fd0c689 1080 ERR("JDR_INP");
WiredHome 115:c9862fd0c689 1081 return JDR_INP;
WiredHome 115:c9862fd0c689 1082 }
WiredHome 115:c9862fd0c689 1083
WiredHome 115:c9862fd0c689 1084 if (!jd->width || !jd->height) {
WiredHome 115:c9862fd0c689 1085 ERR("JDR_FMT1");
WiredHome 115:c9862fd0c689 1086 return JDR_FMT1; /* Err: Invalid image size */
WiredHome 115:c9862fd0c689 1087 }
WiredHome 115:c9862fd0c689 1088
WiredHome 115:c9862fd0c689 1089 if (seg[0] != 3) {
WiredHome 115:c9862fd0c689 1090 ERR("JDR_FMT3");
WiredHome 115:c9862fd0c689 1091 return JDR_FMT3; /* Err: Supports only three color components format */
WiredHome 115:c9862fd0c689 1092 }
WiredHome 115:c9862fd0c689 1093
WiredHome 115:c9862fd0c689 1094 /* Check if all tables corresponding to each components have been loaded */
WiredHome 115:c9862fd0c689 1095 for (i = 0; i < 3; i++) {
WiredHome 115:c9862fd0c689 1096 b = seg[2 + 2 * i]; /* Get huffman table ID */
WiredHome 115:c9862fd0c689 1097 if (b != 0x00 && b != 0x11) {
WiredHome 115:c9862fd0c689 1098 ERR("JDR_FMT3");
WiredHome 115:c9862fd0c689 1099 return JDR_FMT3; /* Err: Different table number for DC/AC element */
WiredHome 115:c9862fd0c689 1100 }
WiredHome 115:c9862fd0c689 1101 b = i ? 1 : 0;
WiredHome 115:c9862fd0c689 1102 if (!jd->huffbits[b][0] || !jd->huffbits[b][1]) { /* Check huffman table for this component */
WiredHome 115:c9862fd0c689 1103 ERR("JDR_FMT1");
WiredHome 115:c9862fd0c689 1104 return JDR_FMT1; /* Err: Huffman table not loaded */
WiredHome 115:c9862fd0c689 1105 }
WiredHome 115:c9862fd0c689 1106 if (!jd->qttbl[jd->qtid[i]]) {
WiredHome 115:c9862fd0c689 1107 ERR("JDR_FMT1");
WiredHome 115:c9862fd0c689 1108 return JDR_FMT1; /* Err: Dequantizer table not loaded */
WiredHome 115:c9862fd0c689 1109 }
WiredHome 115:c9862fd0c689 1110 }
WiredHome 115:c9862fd0c689 1111
WiredHome 115:c9862fd0c689 1112 /* Allocate working buffer for MCU and RGB */
WiredHome 115:c9862fd0c689 1113 n = jd->msy * jd->msx; /* Number of Y blocks in the MCU */
WiredHome 115:c9862fd0c689 1114 if (!n) {
WiredHome 115:c9862fd0c689 1115 ERR("JDR_FMT1");
WiredHome 115:c9862fd0c689 1116 return JDR_FMT1; /* Err: SOF0 has not been loaded */
WiredHome 115:c9862fd0c689 1117 }
WiredHome 115:c9862fd0c689 1118 len = n * 64 * 2 + 64; /* Allocate buffer for IDCT and RGB output */
WiredHome 115:c9862fd0c689 1119 if (len < 256) len = 256; /* but at least 256 byte is required for IDCT */
WiredHome 115:c9862fd0c689 1120 jd->workbuf = alloc_pool(jd, len); /* and it may occupy a part of following MCU working buffer for RGB output */
WiredHome 115:c9862fd0c689 1121 if (!jd->workbuf) {
WiredHome 115:c9862fd0c689 1122 ERR("JDR_MEM1");
WiredHome 115:c9862fd0c689 1123 return JDR_MEM1; /* Err: not enough memory */
WiredHome 115:c9862fd0c689 1124 }
WiredHome 115:c9862fd0c689 1125 jd->mcubuf = (uint8_t *)alloc_pool(jd, (n + 2) * 64); /* Allocate MCU working buffer */
WiredHome 115:c9862fd0c689 1126 if (!jd->mcubuf) {
WiredHome 115:c9862fd0c689 1127 ERR("JDR_MEM1");
WiredHome 115:c9862fd0c689 1128 return JDR_MEM1; /* Err: not enough memory */
WiredHome 115:c9862fd0c689 1129 }
WiredHome 115:c9862fd0c689 1130
WiredHome 115:c9862fd0c689 1131 /* Pre-load the JPEG data to extract it from the bit stream */
WiredHome 115:c9862fd0c689 1132 jd->dptr = seg; jd->dctr = 0; jd->dmsk = 0; /* Prepare to read bit stream */
WiredHome 115:c9862fd0c689 1133 if (ofs %= JD_SZBUF) { /* Align read offset to JD_SZBUF */
WiredHome 115:c9862fd0c689 1134 jd->dctr = getJpegData(jd, seg + ofs, JD_SZBUF - (uint16_t)ofs);
WiredHome 115:c9862fd0c689 1135 jd->dptr = seg + ofs - 1;
WiredHome 115:c9862fd0c689 1136 }
WiredHome 115:c9862fd0c689 1137
WiredHome 115:c9862fd0c689 1138 return JDR_OK; /* Initialization succeeded. Ready to decompress the JPEG image. */
WiredHome 115:c9862fd0c689 1139
WiredHome 115:c9862fd0c689 1140 case 0xC1: /* SOF1 */
WiredHome 115:c9862fd0c689 1141 case 0xC2: /* SOF2 */
WiredHome 115:c9862fd0c689 1142 case 0xC3: /* SOF3 */
WiredHome 115:c9862fd0c689 1143 case 0xC5: /* SOF5 */
WiredHome 115:c9862fd0c689 1144 case 0xC6: /* SOF6 */
WiredHome 115:c9862fd0c689 1145 case 0xC7: /* SOF7 */
WiredHome 115:c9862fd0c689 1146 case 0xC9: /* SOF9 */
WiredHome 115:c9862fd0c689 1147 case 0xCA: /* SOF10 */
WiredHome 115:c9862fd0c689 1148 case 0xCB: /* SOF11 */
WiredHome 115:c9862fd0c689 1149 case 0xCD: /* SOF13 */
WiredHome 115:c9862fd0c689 1150 case 0xCE: /* SOF14 */
WiredHome 115:c9862fd0c689 1151 case 0xCF: /* SOF15 */
WiredHome 115:c9862fd0c689 1152 case 0xD9: /* EOI */
WiredHome 115:c9862fd0c689 1153 return JDR_FMT3; /* Unsuppoted JPEG standard (may be progressive JPEG) */
WiredHome 115:c9862fd0c689 1154
WiredHome 115:c9862fd0c689 1155 default: /* Unknown segment (comment, exif or etc..) */
WiredHome 115:c9862fd0c689 1156 /* Skip segment data */
WiredHome 115:c9862fd0c689 1157 if (getJpegData(jd, 0, len) != len) { /* Null pointer specifies to skip bytes of stream */
WiredHome 115:c9862fd0c689 1158 INFO("Unknown segment");
WiredHome 115:c9862fd0c689 1159 return JDR_INP;
WiredHome 115:c9862fd0c689 1160 }
WiredHome 115:c9862fd0c689 1161 }
WiredHome 115:c9862fd0c689 1162 }
WiredHome 115:c9862fd0c689 1163 }
WiredHome 115:c9862fd0c689 1164
WiredHome 115:c9862fd0c689 1165
WiredHome 115:c9862fd0c689 1166
WiredHome 115:c9862fd0c689 1167
WiredHome 115:c9862fd0c689 1168 /*-----------------------------------------------------------------------*/
WiredHome 115:c9862fd0c689 1169 /* Start to decompress the JPEG picture */
WiredHome 115:c9862fd0c689 1170 /*-----------------------------------------------------------------------*/
WiredHome 115:c9862fd0c689 1171
WiredHome 115:c9862fd0c689 1172 JRESULT GraphicsDisplay::jd_decomp (
WiredHome 115:c9862fd0c689 1173 JDEC * jd, /* Initialized decompression object */
WiredHome 115:c9862fd0c689 1174 uint16_t (*outfunc)(JDEC * jd, void * stream, JRECT * rect), /* RGB output function */
WiredHome 115:c9862fd0c689 1175 uint8_t scale /* Output de-scaling factor (0 to 3) */
WiredHome 115:c9862fd0c689 1176 )
WiredHome 115:c9862fd0c689 1177 {
WiredHome 115:c9862fd0c689 1178 uint16_t x, y, mx, my;
WiredHome 115:c9862fd0c689 1179 uint16_t rst, rsc;
WiredHome 115:c9862fd0c689 1180 JRESULT rc;
WiredHome 115:c9862fd0c689 1181
WiredHome 118:34eb0b64fc61 1182 INFO("jd_decomp(%p,%p,%d)", jd, outfunc, scale);
WiredHome 118:34eb0b64fc61 1183 HexDump("JDEC", (uint8_t *)jd, sizeof(JDEC));
WiredHome 118:34eb0b64fc61 1184
WiredHome 115:c9862fd0c689 1185 if (scale > (JD_USE_SCALE ? 3 : 0)) return JDR_PAR;
WiredHome 115:c9862fd0c689 1186 jd->scale = scale;
WiredHome 115:c9862fd0c689 1187
WiredHome 115:c9862fd0c689 1188 mx = jd->msx * 8; my = jd->msy * 8; /* Size of the MCU (pixel) */
WiredHome 115:c9862fd0c689 1189
WiredHome 115:c9862fd0c689 1190 jd->dcv[2] = jd->dcv[1] = jd->dcv[0] = 0; /* Initialize DC values */
WiredHome 115:c9862fd0c689 1191 rst = rsc = 0;
WiredHome 115:c9862fd0c689 1192
WiredHome 115:c9862fd0c689 1193 rc = JDR_OK;
WiredHome 115:c9862fd0c689 1194 for (y = 0; y < jd->height; y += my) { /* Vertical loop of MCUs */
WiredHome 115:c9862fd0c689 1195 for (x = 0; x < jd->width; x += mx) { /* Horizontal loop of MCUs */
WiredHome 115:c9862fd0c689 1196 if (jd->nrst && rst++ == jd->nrst) { /* Process restart interval if enabled */
WiredHome 115:c9862fd0c689 1197 rc = restart(jd, rsc++);
WiredHome 115:c9862fd0c689 1198 if (rc != JDR_OK) return rc;
WiredHome 115:c9862fd0c689 1199 rst = 1;
WiredHome 115:c9862fd0c689 1200 }
WiredHome 115:c9862fd0c689 1201 rc = mcu_load(jd); /* Load an MCU (decompress huffman coded stream and apply IDCT) */
WiredHome 115:c9862fd0c689 1202 if (rc != JDR_OK) return rc;
WiredHome 115:c9862fd0c689 1203 rc = mcu_output(jd, outfunc, x, y); /* Output the MCU (color space conversion, scaling and output) */
WiredHome 115:c9862fd0c689 1204 if (rc != JDR_OK) return rc;
WiredHome 115:c9862fd0c689 1205 }
WiredHome 115:c9862fd0c689 1206 }
WiredHome 115:c9862fd0c689 1207 return rc;
WiredHome 115:c9862fd0c689 1208 }