kopia lustrzana https://github.com/pimoroni/pimoroni-pico
RGB888 JPEG decode (implemented in some cases only)
rodzic
575e806cc8
commit
a6bd626334
|
@ -12,14 +12,14 @@
|
||||||
|
|
||||||
using namespace pimoroni;
|
using namespace pimoroni;
|
||||||
|
|
||||||
#define FRAME_WIDTH 1280
|
#define FRAME_WIDTH 640
|
||||||
#define FRAME_HEIGHT 720
|
#define FRAME_HEIGHT 720
|
||||||
|
|
||||||
FATFS fs;
|
FATFS fs;
|
||||||
FRESULT fr;
|
FRESULT fr;
|
||||||
|
|
||||||
DVDisplay display(FRAME_WIDTH, FRAME_HEIGHT);
|
DVDisplay display(FRAME_WIDTH, FRAME_HEIGHT, DVDisplay::MODE_RGB888);
|
||||||
PicoGraphics_PenDV_RGB555 graphics(FRAME_WIDTH, FRAME_HEIGHT, display);
|
PicoGraphics_PenDV_RGB888 graphics(FRAME_WIDTH, FRAME_HEIGHT, display);
|
||||||
|
|
||||||
JPEGDEC jpeg;
|
JPEGDEC jpeg;
|
||||||
struct {
|
struct {
|
||||||
|
@ -48,24 +48,26 @@ int32_t jpegdec_seek_callback(JPEGFILE *jpeg, int32_t p) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int jpegdec_draw_callback(JPEGDRAW *draw) {
|
int jpegdec_draw_callback(JPEGDRAW *draw) {
|
||||||
uint16_t *p = draw->pPixels;
|
uint8_t *p = (uint8_t*)draw->pPixels;
|
||||||
|
|
||||||
int xo = jpeg_decode_options.x;
|
int xo = jpeg_decode_options.x;
|
||||||
int yo = jpeg_decode_options.y;
|
int yo = jpeg_decode_options.y;
|
||||||
|
|
||||||
for(int y = 0; y < draw->iHeight; y++) {
|
for(int y = 0; y < draw->iHeight; y++) {
|
||||||
for(int x = 0; x < draw->iWidth; x++) {
|
for(int x = 0; x < draw->iWidth; x+=2) {
|
||||||
int sx = draw->x + x + xo;
|
int sx = ((draw->x + x) >> 1) + xo;
|
||||||
int sy = draw->y + y + yo;
|
int sy = draw->y + y + yo;
|
||||||
|
|
||||||
if(sx >= 0 && sx < graphics.bounds.w && x < draw->iWidthUsed &&
|
if(sx >= 0 && sx < graphics.bounds.w && x < draw->iWidthUsed &&
|
||||||
sy >= 0 && sy < graphics.bounds.h) {
|
sy >= 0 && sy < graphics.bounds.h) {
|
||||||
const RGB565 col = *p;
|
RGB888 col = ((((uint32_t)p[0] + (uint32_t)p[3]) << 15) & 0xff0000) |
|
||||||
graphics.set_pen((col & 0x1F) | ((col & 0xFFC0) >> 1));
|
((((uint32_t)p[1] + (uint32_t)p[4]) << 7) & 0xff00) |
|
||||||
|
(((uint32_t)p[2] + (uint32_t)p[5]) >> 1);
|
||||||
|
graphics.set_pen(col);
|
||||||
graphics.pixel({sx, sy});
|
graphics.pixel({sx, sy});
|
||||||
}
|
}
|
||||||
|
|
||||||
p++;
|
p += 6;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,10 +84,10 @@ void draw_jpeg(std::string filename) {
|
||||||
jpegdec_draw_callback
|
jpegdec_draw_callback
|
||||||
);
|
);
|
||||||
|
|
||||||
jpeg_decode_options.x = (FRAME_WIDTH - jpeg.getWidth()) >> 1;
|
jpeg_decode_options.x = (FRAME_WIDTH - (jpeg.getWidth() >> 1)) >> 1;
|
||||||
jpeg_decode_options.y = (FRAME_HEIGHT - jpeg.getHeight()) >> 1;
|
jpeg_decode_options.y = (FRAME_HEIGHT - jpeg.getHeight()) >> 1;
|
||||||
|
|
||||||
jpeg.setPixelType(RGB565_LITTLE_ENDIAN);
|
jpeg.setPixelType(RGB888_LITTLE_ENDIAN);
|
||||||
|
|
||||||
printf("- starting jpeg decode..");
|
printf("- starting jpeg decode..");
|
||||||
int start = millis();
|
int start = millis();
|
||||||
|
|
|
@ -46,7 +46,7 @@ int main() {
|
||||||
gpio_set_dir(BUTTON_A, GPIO_IN);
|
gpio_set_dir(BUTTON_A, GPIO_IN);
|
||||||
gpio_pull_up(BUTTON_A);
|
gpio_pull_up(BUTTON_A);
|
||||||
|
|
||||||
sleep_ms(5000);
|
//sleep_ms(5000);
|
||||||
|
|
||||||
DVDisplay display(FRAME_WIDTH, FRAME_HEIGHT, DVDisplay::MODE_RGB888);
|
DVDisplay display(FRAME_WIDTH, FRAME_HEIGHT, DVDisplay::MODE_RGB888);
|
||||||
display.init();
|
display.init();
|
||||||
|
@ -120,8 +120,15 @@ int main() {
|
||||||
//}
|
//}
|
||||||
uint32_t render_start_time = time_us_32();
|
uint32_t render_start_time = time_us_32();
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
for (int j = 0; j < FRAME_HEIGHT; ++j) {
|
||||||
|
graphics.set_pen(j, 0xFF, 0xFF);
|
||||||
|
graphics.pixel_span({0,j}, FRAME_WIDTH);
|
||||||
|
}
|
||||||
|
#else
|
||||||
graphics.set_pen(0xFF, 0xFF, 0xFF);
|
graphics.set_pen(0xFF, 0xFF, 0xFF);
|
||||||
graphics.clear();
|
graphics.clear();
|
||||||
|
#endif
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
for (uint i = 0; i < 128; i++) {
|
for (uint i = 0; i < 128; i++) {
|
||||||
|
|
|
@ -68,6 +68,7 @@
|
||||||
enum {
|
enum {
|
||||||
RGB565_LITTLE_ENDIAN = 0,
|
RGB565_LITTLE_ENDIAN = 0,
|
||||||
RGB565_BIG_ENDIAN,
|
RGB565_BIG_ENDIAN,
|
||||||
|
RGB888_LITTLE_ENDIAN,
|
||||||
EIGHT_BIT_GRAYSCALE,
|
EIGHT_BIT_GRAYSCALE,
|
||||||
FOUR_BIT_DITHERED,
|
FOUR_BIT_DITHERED,
|
||||||
TWO_BIT_DITHERED,
|
TWO_BIT_DITHERED,
|
||||||
|
|
|
@ -2210,7 +2210,6 @@ static void JPEGPixel2BE(uint16_t *pDest, int32_t iY1, int32_t iY2, int32_t iCb,
|
||||||
*(uint32_t *)&pDest[0] = __builtin_bswap16(ulPixel1) | ((uint32_t)__builtin_bswap16(ulPixel2)<<16);
|
*(uint32_t *)&pDest[0] = __builtin_bswap16(ulPixel1) | ((uint32_t)__builtin_bswap16(ulPixel2)<<16);
|
||||||
} /* JPEGPixel2BE() */
|
} /* JPEGPixel2BE() */
|
||||||
|
|
||||||
#if 0
|
|
||||||
static void JPEGPixelLE888(uint8_t *pDest, int iY, int iCb, int iCr)
|
static void JPEGPixelLE888(uint8_t *pDest, int iY, int iCb, int iCr)
|
||||||
{
|
{
|
||||||
int32_t iCBB, iCBG, iCRG, iCRR;
|
int32_t iCBB, iCBG, iCRG, iCRR;
|
||||||
|
@ -2236,7 +2235,6 @@ static void JPEGPixelLE888(uint8_t *pDest, int iY, int iCb, int iCr)
|
||||||
if (uVal & 0x100) uVal = 0;
|
if (uVal & 0x100) uVal = 0;
|
||||||
*pDest++ = uVal;
|
*pDest++ = uVal;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static void JPEGPutMCU11(JPEGIMAGE *pJPEG, int x, int iPitch)
|
static void JPEGPutMCU11(JPEGIMAGE *pJPEG, int x, int iPitch)
|
||||||
{
|
{
|
||||||
|
@ -2246,6 +2244,7 @@ static void JPEGPutMCU11(JPEGIMAGE *pJPEG, int x, int iPitch)
|
||||||
int iRow;
|
int iRow;
|
||||||
uint8_t *pY, *pCr, *pCb;
|
uint8_t *pY, *pCr, *pCb;
|
||||||
uint16_t *pOutput = &pJPEG->usPixels[x];
|
uint16_t *pOutput = &pJPEG->usPixels[x];
|
||||||
|
uint8_t *pOutput8 = ((uint8_t*)pJPEG->usPixels) + x * 3;
|
||||||
|
|
||||||
pY = (unsigned char *)&pJPEG->sMCUs[0*DCTSIZE];
|
pY = (unsigned char *)&pJPEG->sMCUs[0*DCTSIZE];
|
||||||
pCb = (unsigned char *)&pJPEG->sMCUs[1*DCTSIZE];
|
pCb = (unsigned char *)&pJPEG->sMCUs[1*DCTSIZE];
|
||||||
|
@ -2342,6 +2341,17 @@ static void JPEGPutMCU11(JPEGIMAGE *pJPEG, int x, int iPitch)
|
||||||
JPEGPixelLE(pOutput+iCol, Y, iCb, iCr);
|
JPEGPixelLE(pOutput+iCol, Y, iCb, iCr);
|
||||||
} // for col
|
} // for col
|
||||||
}
|
}
|
||||||
|
else if (pJPEG->ucPixelType == RGB888_LITTLE_ENDIAN)
|
||||||
|
{
|
||||||
|
for (iCol=0; iCol<8; iCol++) // up to 4x2 cols to do
|
||||||
|
{
|
||||||
|
iCr = *pCr++;
|
||||||
|
iCb = *pCb++;
|
||||||
|
Y = (int)(*pY++) << 12;
|
||||||
|
JPEGPixelLE888(pOutput8+iCol*3, Y, iCb, iCr);
|
||||||
|
} // for col
|
||||||
|
pOutput8 += iPitch * 3;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (iCol=0; iCol<8; iCol++) // up to 4x2 cols to do
|
for (iCol=0; iCol<8; iCol++) // up to 4x2 cols to do
|
||||||
|
@ -2697,6 +2707,7 @@ static void JPEGPutMCU12(JPEGIMAGE *pJPEG, int x, int iPitch)
|
||||||
int iRow, iCol, iXCount, iYCount;
|
int iRow, iCol, iXCount, iYCount;
|
||||||
uint8_t *pY, *pCr, *pCb;
|
uint8_t *pY, *pCr, *pCb;
|
||||||
uint16_t *pOutput = &pJPEG->usPixels[x];
|
uint16_t *pOutput = &pJPEG->usPixels[x];
|
||||||
|
uint8_t *pOutput8 = ((uint8_t*)pJPEG->usPixels) + x * 3;
|
||||||
|
|
||||||
pY = (uint8_t *)&pJPEG->sMCUs[0*DCTSIZE];
|
pY = (uint8_t *)&pJPEG->sMCUs[0*DCTSIZE];
|
||||||
pCb = (uint8_t *)&pJPEG->sMCUs[2*DCTSIZE];
|
pCb = (uint8_t *)&pJPEG->sMCUs[2*DCTSIZE];
|
||||||
|
@ -2828,6 +2839,11 @@ static void JPEGPutMCU12(JPEGIMAGE *pJPEG, int x, int iPitch)
|
||||||
JPEGPixelLE(pOutput + iCol, Y1, Cb, Cr);
|
JPEGPixelLE(pOutput + iCol, Y1, Cb, Cr);
|
||||||
JPEGPixelLE(pOutput + iPitch + iCol, Y2, Cb, Cr);
|
JPEGPixelLE(pOutput + iPitch + iCol, Y2, Cb, Cr);
|
||||||
}
|
}
|
||||||
|
else if (pJPEG->ucPixelType == RGB888_LITTLE_ENDIAN)
|
||||||
|
{
|
||||||
|
JPEGPixelLE888(pOutput8 + iCol*3, Y1, Cb, Cr);
|
||||||
|
JPEGPixelLE888(pOutput8 + (iPitch + iCol)*3, Y2, Cb, Cr);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
JPEGPixelBE(pOutput + iCol, Y1, Cb, Cr);
|
JPEGPixelBE(pOutput + iCol, Y1, Cb, Cr);
|
||||||
|
@ -2840,6 +2856,7 @@ static void JPEGPutMCU12(JPEGIMAGE *pJPEG, int x, int iPitch)
|
||||||
pCb += 8;
|
pCb += 8;
|
||||||
pCr += 8;
|
pCr += 8;
|
||||||
pOutput += iPitch*2; // next 2 lines of dest pixels
|
pOutput += iPitch*2; // next 2 lines of dest pixels
|
||||||
|
pOutput8 += iPitch*6;
|
||||||
}
|
}
|
||||||
} /* JPEGPutMCU12() */
|
} /* JPEGPutMCU12() */
|
||||||
static void JPEGPutMCU21(JPEGIMAGE *pJPEG, int x, int iPitch)
|
static void JPEGPutMCU21(JPEGIMAGE *pJPEG, int x, int iPitch)
|
||||||
|
@ -3097,6 +3114,8 @@ static int DecodeJPEG(JPEGIMAGE *pJPEG)
|
||||||
cDCTable2 = pJPEG->JPCI[2].dc_tbl_no;
|
cDCTable2 = pJPEG->JPCI[2].dc_tbl_no;
|
||||||
cACTable2 = pJPEG->JPCI[2].ac_tbl_no;
|
cACTable2 = pJPEG->JPCI[2].ac_tbl_no;
|
||||||
iDCPred0 = iDCPred1 = iDCPred2 = mcuCX = mcuCY = 0;
|
iDCPred0 = iDCPred1 = iDCPred2 = mcuCX = mcuCY = 0;
|
||||||
|
|
||||||
|
printf("SubSample mode: 0x%x\n", pJPEG->ucSubSample);
|
||||||
|
|
||||||
switch (pJPEG->ucSubSample) // set up the parameters for the different subsampling options
|
switch (pJPEG->ucSubSample) // set up the parameters for the different subsampling options
|
||||||
{
|
{
|
||||||
|
@ -3155,6 +3174,8 @@ static int DecodeJPEG(JPEGIMAGE *pJPEG)
|
||||||
iMCUCount = MAX_BUFFERED_PIXELS / (mcuCX * mcuCY);
|
iMCUCount = MAX_BUFFERED_PIXELS / (mcuCX * mcuCY);
|
||||||
if (pJPEG->ucPixelType == EIGHT_BIT_GRAYSCALE)
|
if (pJPEG->ucPixelType == EIGHT_BIT_GRAYSCALE)
|
||||||
iMCUCount *= 2; // each pixel is only 1 byte
|
iMCUCount *= 2; // each pixel is only 1 byte
|
||||||
|
else if (pJPEG->ucPixelType == RGB888_LITTLE_ENDIAN)
|
||||||
|
iMCUCount = (iMCUCount >> 1) + (iMCUCount >> 3); // each picel is 3 bytes
|
||||||
if (iMCUCount > cx)
|
if (iMCUCount > cx)
|
||||||
iMCUCount = cx; // don't go wider than the image
|
iMCUCount = cx; // don't go wider than the image
|
||||||
if (iMCUCount > pJPEG->iMaxMCUs) // did the user set an upper bound on how many pixels per JPEGDraw callback?
|
if (iMCUCount > pJPEG->iMaxMCUs) // did the user set an upper bound on how many pixels per JPEGDraw callback?
|
||||||
|
@ -3164,6 +3185,9 @@ static int DecodeJPEG(JPEGIMAGE *pJPEG)
|
||||||
jd.iBpp = 16;
|
jd.iBpp = 16;
|
||||||
switch (pJPEG->ucPixelType)
|
switch (pJPEG->ucPixelType)
|
||||||
{
|
{
|
||||||
|
case RGB888_LITTLE_ENDIAN:
|
||||||
|
jd.iBpp = 24;
|
||||||
|
break;
|
||||||
case EIGHT_BIT_GRAYSCALE:
|
case EIGHT_BIT_GRAYSCALE:
|
||||||
jd.iBpp = 8;
|
jd.iBpp = 8;
|
||||||
break;
|
break;
|
||||||
|
|
Ładowanie…
Reference in New Issue