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

◆ mcu_output()

static JRESULT fl::third_party::mcu_output ( JDEC * jd,
int(* outfunc )(JDEC *, void *, JRECT *),
unsigned int x,
unsigned int y )
static

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

803{
804 const int CVACC = (sizeof (int) > 2) ? 1024 : 128; /* Adaptive accuracy for both 16-/32-bit systems */
805 unsigned int ix, iy, mx, my, rx, ry;
806 int yy, cb, cr;
807 jd_yuv_t *py, *pc;
808 uint8_t *pix;
809 JRECT rect;
810
811
812 mx = jd->msx * 8; my = jd->msy * 8; /* MCU size (pixel) */
813 rx = (x + mx <= jd->width) ? mx : jd->width - x; /* Output rectangular size (it may be clipped at right/bottom end of image) */
814 ry = (y + my <= jd->height) ? my : jd->height - y;
815 if (JD_USE_SCALE) {
816 rx >>= jd->scale; ry >>= jd->scale;
817 if (!rx || !ry) return JDR_OK; /* Skip this MCU if all pixel is to be rounded off */
818 x >>= jd->scale; y >>= jd->scale;
819 }
820 rect.left = x; rect.right = x + rx - 1; /* Rectangular area in the frame buffer */
821 rect.top = y; rect.bottom = y + ry - 1;
822
823
824 if (!JD_USE_SCALE || jd->scale != 3) { /* Not for 1/8 scaling */
825 pix = (uint8_t*)jd->workbuf;
826
827 if (JD_FORMAT != 2) { /* RGB output (build an RGB MCU from Y/C component) */
828 for (iy = 0; iy < my; iy++) {
829 pc = py = jd->mcubuf;
830 if (my == 16) { /* Double block height? */
831 pc += 64 * 4 + (iy >> 1) * 8;
832 if (iy >= 8) py += 64;
833 } else { /* Single block height */
834 pc += mx * 8 + iy * 8;
835 }
836 py += iy * 8;
837 for (ix = 0; ix < mx; ix++) {
838 cb = pc[0] - 128; /* Get Cb/Cr component and remove offset */
839 cr = pc[64] - 128;
840 if (mx == 16) { /* Double block width? */
841 if (ix == 8) py += 64 - 8; /* Jump to next block if double block heigt */
842 pc += ix & 1; /* Step forward chroma pointer every two pixels */
843 } else { /* Single block width */
844 pc++; /* Step forward chroma pointer every pixel */
845 }
846 yy = *py++; /* Get Y component */
847 *pix++ = /*R*/ BYTECLIP(yy + ((int)(1.402 * CVACC) * cr) / CVACC);
848 *pix++ = /*G*/ BYTECLIP(yy - ((int)(0.344 * CVACC) * cb + (int)(0.714 * CVACC) * cr) / CVACC);
849 *pix++ = /*B*/ BYTECLIP(yy + ((int)(1.772 * CVACC) * cb) / CVACC);
850 }
851 }
852 } else { /* Monochrome output (build a grayscale MCU from Y comopnent) */
853 for (iy = 0; iy < my; iy++) {
854 py = jd->mcubuf + iy * 8;
855 if (my == 16) { /* Double block height? */
856 if (iy >= 8) py += 64;
857 }
858 for (ix = 0; ix < mx; ix++) {
859 if (mx == 16) { /* Double block width? */
860 if (ix == 8) py += 64 - 8; /* Jump to next block if double block height */
861 }
862 if (JD_FASTDECODE >= 1) {
863 *pix++ = BYTECLIP(*py++); /* Get and store a Y value as grayscale */
864 } else {
865 *pix++ = *py++; /* Get and store a Y value as grayscale */
866 }
867 }
868 }
869 }
870
871 /* Descale the MCU rectangular if needed */
872 if (JD_USE_SCALE && jd->scale) {
873 unsigned int x, y, r, g, b, s, w, a;
874 uint8_t *op;
875
876 /* Get averaged RGB value of each square correcponds to a pixel */
877 s = jd->scale * 2; /* Number of shifts for averaging */
878 w = 1 << jd->scale; /* Width of square */
879 a = (mx - w) * (JD_FORMAT != 2 ? 3 : 1); /* Bytes to skip for next line in the square */
880 op = (uint8_t*)jd->workbuf;
881 for (iy = 0; iy < my; iy += w) {
882 for (ix = 0; ix < mx; ix += w) {
883 pix = (uint8_t*)jd->workbuf + (iy * mx + ix) * (JD_FORMAT != 2 ? 3 : 1);
884 r = g = b = 0;
885 for (y = 0; y < w; y++) { /* Accumulate RGB value in the square */
886 for (x = 0; x < w; x++) {
887 r += *pix++; /* Accumulate R or Y (monochrome output) */
888 if (JD_FORMAT != 2) { /* RGB output? */
889 g += *pix++; /* Accumulate G */
890 b += *pix++; /* Accumulate B */
891 }
892 }
893 pix += a;
894 } /* Put the averaged pixel value */
895 *op++ = (uint8_t)(r >> s); /* Put R or Y (monochrome output) */
896 if (JD_FORMAT != 2) { /* RGB output? */
897 *op++ = (uint8_t)(g >> s); /* Put G */
898 *op++ = (uint8_t)(b >> s); /* Put B */
899 }
900 }
901 }
902 }
903
904 } else { /* For only 1/8 scaling (left-top pixel in each block are the DC value of the block) */
905
906 /* Build a 1/8 descaled RGB MCU from discrete comopnents */
907 pix = (uint8_t*)jd->workbuf;
908 pc = jd->mcubuf + mx * my;
909 cb = pc[0] - 128; /* Get Cb/Cr component and restore right level */
910 cr = pc[64] - 128;
911 for (iy = 0; iy < my; iy += 8) {
912 py = jd->mcubuf;
913 if (iy == 8) py += 64 * 2;
914 for (ix = 0; ix < mx; ix += 8) {
915 yy = *py; /* Get Y component */
916 py += 64;
917 if (JD_FORMAT != 2) {
918 *pix++ = /*R*/ BYTECLIP(yy + ((int)(1.402 * CVACC) * cr / CVACC));
919 *pix++ = /*G*/ BYTECLIP(yy - ((int)(0.344 * CVACC) * cb + (int)(0.714 * CVACC) * cr) / CVACC);
920 *pix++ = /*B*/ BYTECLIP(yy + ((int)(1.772 * CVACC) * cb / CVACC));
921 } else {
922 *pix++ = yy;
923 }
924 }
925 }
926 }
927
928 /* Squeeze up pixel table if a part of MCU is to be truncated */
929 mx >>= jd->scale;
930 if (rx < mx) { /* Is the MCU spans rigit edge? */
931 uint8_t *s, *d;
932 unsigned int x, y;
933
934 s = d = (uint8_t*)jd->workbuf;
935 for (y = 0; y < ry; y++) {
936 for (x = 0; x < rx; x++) { /* Copy effective pixels */
937 *d++ = *s++;
938 if (JD_FORMAT != 2) {
939 *d++ = *s++;
940 *d++ = *s++;
941 }
942 }
943 s += (mx - rx) * (JD_FORMAT != 2 ? 3 : 1); /* Skip truncated pixels */
944 }
945 }
946
947 /* Convert RGB888 to RGB565 if needed */
948 if (JD_FORMAT == 1) {
949 uint8_t *s = (uint8_t*)jd->workbuf;
950 uint16_t w, *d = (uint16_t*)s;
951 unsigned int n = rx * ry;
952
953 if (jd->swap)
954 {
955 do {
956 w = (*s++ & 0xF8) << 8; // RRRRR-----------
957 w |= (*s++ & 0xFC) << 3; // -----GGGGGG-----
958 w |= *s++ >> 3; // -----------BBBBB
959 *d++ = (w << 8) | (w >> 8); // Swap bytes
960 } while (--n);
961 }
962 else
963 {
964 do {
965 w = ( *s++ & 0xF8) << 8; // RRRRR-----------
966 w |= (*s++ & 0xFC) << 3; // -----GGGGGG-----
967 w |= *s++ >> 3; // -----------BBBBB
968 *d++ = w;
969 } while (--n);
970 }
971 }
972
973 /* Output the rectangular */
974 return outfunc(jd, jd->workbuf, &rect) ? JDR_OK : JDR_INTR;
975}
static uint8_t BYTECLIP(int val) FL_NOEXCEPT
fl::u16 uint16_t
Definition coder.h:214
unsigned char uint8_t
Definition coder.h:209
uint8_t jd_yuv_t
Definition tjpgd.h:19
jd_yuv_t * mcubuf
Definition tjpgd.h:76
uint16_t height
Definition tjpgd.h:61
u8 u8 height
Definition blur.h:186
u8 width
Definition blur.h:186
unsigned char uint8_t
Definition s16x16x4.h:209
#define JD_FORMAT
Definition tjpgdcnf.h:8
#define JD_FASTDECODE
Definition tjpgdcnf.h:27
#define JD_USE_SCALE
Definition tjpgdcnf.h:15

References BYTECLIP(), FL_NOEXCEPT, fl::third_party::JDEC::height, JD_FASTDECODE, JD_FORMAT, JD_USE_SCALE, JDR_INTR, JDR_OK, fl::third_party::JDEC::mcubuf, fl::third_party::JDEC::msx, fl::third_party::JDEC::msy, fl::third_party::JDEC::scale, fl::third_party::JDEC::swap, fl::third_party::JDEC::width, fl::third_party::JDEC::workbuf, fl::x, and fl::y.

Referenced by jd_decomp(), and jd_decomp_progressive().

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