FastLED 3.9.15
Loading...
Searching...
No Matches

◆ jd_prepare()

JRESULT fl::third_party::jd_prepare ( JDEC * jd,
size_t(* infunc )(JDEC *, uint8_t *, size_t),
void * pool,
size_t sz_pool,
void * dev )

Definition at line 987 of file tjpgd.cpp.hpp.

994{
995 uint8_t *seg, b;
996 uint16_t marker;
997 unsigned int n, i, ofs;
998 size_t len;
999 JRESULT rc;
1000
1001 uint8_t tmp = jd->swap; // Copy the swap flag
1002 fl::memset(jd, 0, sizeof (JDEC)); /* Clear decompression object (this might be a problem if machine's null pointer is not all bits zero) */
1003 jd->pool = pool; /* Work memroy */
1004 jd->sz_pool = sz_pool; /* Size of given work memory */
1005 jd->infunc = infunc; /* Stream input function */
1006 jd->device = dev; /* I/O device identifier */
1007 jd->swap = tmp; // Restore the swap flag
1008
1009 jd->inbuf = seg = (uint8_t*)alloc_pool(jd, JD_SZBUF); /* Allocate stream input buffer */
1010 if (!seg) return JDR_MEM1;
1011
1012 ofs = marker = 0; /* Find SOI marker */
1013 do {
1014 if (jd->infunc(jd, seg, 1) != 1) return JDR_INP; /* Err: SOI was not detected */
1015 ofs++;
1016 marker = marker << 8 | seg[0];
1017 } while (marker != 0xFFD8);
1018
1019 for (;;) { /* Parse JPEG segments */
1020 /* Get a JPEG marker */
1021 if (jd->infunc(jd, seg, 4) != 4) return JDR_INP;
1022 marker = LDB_WORD(seg); /* Marker */
1023 len = LDB_WORD(seg + 2); /* Length field */
1024 if (len <= 2 || (marker >> 8) != 0xFF) return JDR_FMT1;
1025 len -= 2; /* Segent content size */
1026 ofs += 4 + len; /* Number of bytes loaded */
1027
1028 switch (marker & 0xFF) {
1029 case 0xC0: /* SOF0 (baseline JPEG) */
1030 if (len > JD_SZBUF) return JDR_MEM2;
1031 if (jd->infunc(jd, seg, len) != len) return JDR_INP; /* Load segment data */
1032
1033 jd->width = LDB_WORD(&seg[3]); /* Image width in unit of pixel */
1034 jd->height = LDB_WORD(&seg[1]); /* Image height in unit of pixel */
1035 jd->ncomp = seg[5]; /* Number of color components */
1036 if (jd->ncomp != 3 && jd->ncomp != 1) return JDR_FMT3; /* Err: Supports only Grayscale and Y/Cb/Cr */
1037
1038 /* Check each image component */
1039 for (i = 0; i < jd->ncomp; i++) {
1040 b = seg[7 + 3 * i]; /* Get sampling factor */
1041 if (i == 0) { /* Y component */
1042 if (b != 0x11 && b != 0x22 && b != 0x21) { /* Check sampling factor */
1043 return JDR_FMT3; /* Err: Supports only 4:4:4, 4:2:0 or 4:2:2 */
1044 }
1045 jd->msx = b >> 4; jd->msy = b & 15; /* Size of MCU [blocks] */
1046 } else { /* Cb/Cr component */
1047 if (b != 0x11) return JDR_FMT3; /* Err: Sampling factor of Cb/Cr must be 1 */
1048 }
1049 jd->qtid[i] = seg[8 + 3 * i]; /* Get dequantizer table ID for this component */
1050 if (jd->qtid[i] > 3) return JDR_FMT3; /* Err: Invalid ID */
1051 }
1052 break;
1053
1054 case 0xDD: /* DRI - Define Restart Interval */
1055 if (len > JD_SZBUF) return JDR_MEM2;
1056 if (jd->infunc(jd, seg, len) != len) return JDR_INP; /* Load segment data */
1057
1058 jd->nrst = LDB_WORD(seg); /* Get restart interval (MCUs) */
1059 break;
1060
1061 case 0xC4: /* DHT - Define Huffman Tables */
1062 if (len > JD_SZBUF) return JDR_MEM2;
1063 if (jd->infunc(jd, seg, len) != len) return JDR_INP; /* Load segment data */
1064
1065 rc = create_huffman_tbl(jd, seg, len); /* Create huffman tables */
1066 if (rc) return rc;
1067 break;
1068
1069 case 0xDB: /* DQT - Define Quaitizer Tables */
1070 if (len > JD_SZBUF) return JDR_MEM2;
1071 if (jd->infunc(jd, seg, len) != len) return JDR_INP; /* Load segment data */
1072
1073 rc = create_qt_tbl(jd, seg, len); /* Create de-quantizer tables */
1074 if (rc) return rc;
1075 break;
1076
1077 case 0xDA: /* SOS - Start of Scan */
1078 if (len > JD_SZBUF) return JDR_MEM2;
1079 if (jd->infunc(jd, seg, len) != len) return JDR_INP; /* Load segment data */
1080
1081 if (!jd->width || !jd->height) return JDR_FMT1; /* Err: Invalid image size */
1082 if (seg[0] != jd->ncomp) return JDR_FMT3; /* Err: Wrong color components */
1083
1084 /* Check if all tables corresponding to each components have been loaded */
1085 for (i = 0; i < jd->ncomp; i++) {
1086 b = seg[2 + 2 * i]; /* Get huffman table ID */
1087 if (b != 0x00 && b != 0x11) return JDR_FMT3; /* Err: Different table number for DC/AC element */
1088 n = i ? 1 : 0; /* Component class */
1089 if (!jd->huffbits[n][0] || !jd->huffbits[n][1]) { /* Check huffman table for this component */
1090 return JDR_FMT1; /* Err: Nnot loaded */
1091 }
1092 if (!jd->qttbl[jd->qtid[i]]) { /* Check dequantizer table for this component */
1093 return JDR_FMT1; /* Err: Not loaded */
1094 }
1095 }
1096
1097 /* Allocate working buffer for MCU and pixel output */
1098 n = jd->msy * jd->msx; /* Number of Y blocks in the MCU */
1099 if (!n) return JDR_FMT1; /* Err: SOF0 has not been loaded */
1100 len = n * 64 * 2 + 64; /* Allocate buffer for IDCT and RGB output */
1101 if (len < 256) len = 256; /* but at least 256 byte is required for IDCT */
1102 jd->workbuf = alloc_pool(jd, len); /* and it may occupy a part of following MCU working buffer for RGB output */
1103 if (!jd->workbuf) return JDR_MEM1; /* Err: not enough memory */
1104 jd->mcubuf = (jd_yuv_t*)alloc_pool(jd, (n + 2) * 64 * sizeof (jd_yuv_t)); /* Allocate MCU working buffer */
1105 if (!jd->mcubuf) return JDR_MEM1; /* Err: not enough memory */
1106
1107 /* Align stream read offset to JD_SZBUF */
1108 if (ofs %= JD_SZBUF) {
1109 jd->dctr = jd->infunc(jd, seg + ofs, (size_t)(JD_SZBUF - ofs));
1110 }
1111 jd->dptr = seg + ofs - (JD_FASTDECODE ? 0 : 1);
1112
1113 return JDR_OK; /* Initialization succeeded. Ready to decompress the JPEG image. */
1114
1115 case 0xC1: /* SOF1 */
1116 case 0xC2: /* SOF2 */
1117 case 0xC3: /* SOF3 */
1118 case 0xC5: /* SOF5 */
1119 case 0xC6: /* SOF6 */
1120 case 0xC7: /* SOF7 */
1121 case 0xC9: /* SOF9 */
1122 case 0xCA: /* SOF10 */
1123 case 0xCB: /* SOF11 */
1124 case 0xCD: /* SOF13 */
1125 case 0xCE: /* SOF14 */
1126 case 0xCF: /* SOF15 */
1127 case 0xD9: /* EOI */
1128 return JDR_FMT3; /* Unsuppoted JPEG standard (may be progressive JPEG) */
1129
1130 default: /* Unknown segment (comment, exif or etc..) */
1131 /* Skip segment data (null pointer specifies to remove data from the stream) */
1132 if (jd->infunc(jd, 0, len) != len) return JDR_INP;
1133 }
1134 }
1135}
static JRESULT create_huffman_tbl(JDEC *jd, const uint8_t *data, size_t ndata) FL_NOEXCEPT
static JRESULT create_qt_tbl(JDEC *jd, const uint8_t *data, size_t ndata) FL_NOEXCEPT
fl::u16 uint16_t
Definition coder.h:214
static void * alloc_pool(JDEC *jd, size_t ndata) FL_NOEXCEPT
unsigned char uint8_t
Definition coder.h:209
uint8_t jd_yuv_t
Definition tjpgd.h:19
uint8_t qtid[3]
Definition tjpgd.h:57
jd_yuv_t * mcubuf
Definition tjpgd.h:76
uint8_t * dptr
Definition tjpgd.h:52
size_t(* infunc)(JDEC *, uint8_t *, size_t)
Definition tjpgd.h:79
uint8_t * inbuf
Definition tjpgd.h:53
uint16_t height
Definition tjpgd.h:61
uint8_t * huffbits[2][2]
Definition tjpgd.h:62
int32_t * qttbl[4]
Definition tjpgd.h:65
void * memset(void *s, int c, size_t n) FL_NOEXCEPT
#define LDB_WORD(ptr)
#define JD_SZBUF
Definition tjpgdcnf.h:5
#define JD_FASTDECODE
Definition tjpgdcnf.h:27

References alloc_pool(), create_huffman_tbl(), create_qt_tbl(), fl::third_party::JDEC::dctr, fl::third_party::JDEC::device, fl::third_party::JDEC::dptr, FL_NOEXCEPT, fl::third_party::JDEC::height, fl::third_party::JDEC::huffbits, fl::third_party::JDEC::inbuf, fl::third_party::JDEC::infunc, JD_FASTDECODE, JD_SZBUF, JDR_FMT1, JDR_FMT3, JDR_INP, JDR_MEM1, JDR_MEM2, JDR_OK, LDB_WORD, fl::third_party::JDEC::mcubuf, fl::memset(), fl::third_party::JDEC::msx, fl::third_party::JDEC::msy, fl::third_party::JDEC::ncomp, fl::third_party::JDEC::nrst, fl::third_party::JDEC::pool, fl::third_party::JDEC::qtid, fl::third_party::JDEC::qttbl, fl::third_party::JDEC::swap, fl::third_party::JDEC::sz_pool, fl::third_party::JDEC::width, and fl::third_party::JDEC::workbuf.

Referenced by fl::third_party::TJpg_Decoder::drawJpg(), fl::third_party::TJpg_Decoder::getJpgSize(), and fl::third_party::TJpgInstanceDecoder::initializeDecoder().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: