imageviewer/jpegp: decode RGB images

jpegp converted every image from YCbCr, so RGB JPEGs showed scrambled
colours. That affects progressive RGB files, and now also baseline RGB
files the jpeg decoder rejects and hands on to jpegp, such as RGB with
the R component sampled 2x2.

Record the JFIF and Adobe APP14 markers, decide the colour space with
the same rule as the other decoders, and skip the YUV conversion for
RGB.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Change-Id: If023eeb612b7f8a891d21fbe0070ab43c5a08f17
This commit is contained in:
Michael Giacomelli 2026-09-29 20:37:25 -04:00 • committed by Solomon Peachy
parent 142a6fbb39
commit 9936e65e6d
3 changed files with 20 additions and 2 deletions

View file

@ -43,6 +43,7 @@ jpeg81.c
#include "GETC.h"
#include "rb_glue.h"
#include "jpeg81.h"
#include "jpeg_common.h"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
@ -982,8 +983,15 @@ extern enum JPEGENUM JPEGDecode(struct JPEGD *j)
}
else if ( (marker & 0xf0) == 0xE0 ) // APPn E0..EF
{
int La= GETWbi();
SEEK(La-2);
int La= GETWbi()-2;
int n= 0;
if ( marker == 0xE0 || marker == 0xEE ) // JFIF, Adobe: colour space
{
unsigned char id[12];
for ( ; n < La && n < 12; n++ ) id[n]= GETC();
jpeg_app_colorspace(marker, id, n, &j->jfif, &j->adobe);
}
SEEK(La-n);
printf("APP%d\n", marker&15);
}
else if ( marker == 0xFE ) // COM

View file

@ -34,6 +34,8 @@ enum JPEGENUM {
JPEGENUMERR_COMPNOTFOUND, // Scan component selector (Csj) not found among Component identifiers (Ci)
};
#include <stdbool.h>
typedef short TCOEF; // 16-bit coefficients
typedef TCOEF DU[64]; // The DATA UNIT
typedef unsigned short TSAMP; // Lossless 'coefficients' are unsigned
@ -103,6 +105,8 @@ struct JPEGD { // The JPEG DECODER OBJECT
void *jpeg_mem; // <-- free me
int Hmax, Vmax; // for conversion
bool jfif; // saw a JFIF APP0 marker
unsigned char adobe; // Adobe APP14 transform flag + 1, 0 if none
int mcu_width;
int mcu_height;
int mcu_total; // covers the whole image

View file

@ -4,6 +4,7 @@
#include "rb_glue.h"
#include "../imageviewer.h"
#include "jpeg_common.h"
/**************** begin Application ********************/
@ -217,6 +218,8 @@ static int get_image(struct image_info *info, int frame, int ds)
int v1 = j->Vmax / j->Components[1].Vi;
int h2 = j->Hmax / j->Components[2].Hi;
int v2 = j->Vmax / j->Components[2].Vi;
bool rgb = jpeg_is_rgb(j->jfif, j->adobe, j->Components[0].Ci,
j->Components[1].Ci, j->Components[2].Ci);
int x, y;
int max_y = info->height * ds;
@ -264,6 +267,9 @@ static int get_image(struct image_info *info, int frame, int ds)
c2 = (sumV + area/2) / area;
}
if (rgb) // components are R, G, B: no conversion
*bmp++= FB_RGBPACK(c0, c1, c2);
else
// ITU BT.601 full-range YUV-to-RGB integer approximation
{
int y = (c0 << 5) + 16;