- added JPEG YCCK decoding.

Just for completeness - the formula was pieced together from stb_image's handling.
This commit is contained in:
Christoph Oelckers 2022-05-12 12:12:31 +02:00
parent e639030276
commit beeb5f00aa
3 changed files with 37 additions and 1 deletions

View file

@ -209,13 +209,14 @@ typedef void (*CopyFunc)(uint8_t *pout, const uint8_t *pin, int count, int step,
iCopyColors<cIA, cBGRA, op>, \
iCopyColors<cCMYK, cBGRA, op>, \
iCopyColors<cYCbCr, cBGRA, op>, \
iCopyColors<cYCCK, cBGRA, op>, \
iCopyColors<cBGR, cBGRA, op>, \
iCopyColors<cBGRA, cBGRA, op>, \
iCopyColors<cI16, cBGRA, op>, \
iCopyColors<cRGB555, cBGRA, op>, \
iCopyColors<cPalEntry, cBGRA, op> \
}
static const CopyFunc copyfuncs[][11]={
static const CopyFunc copyfuncs[][12]={
COPY_FUNCS(bCopy),
COPY_FUNCS(bBlend),
COPY_FUNCS(bAdd),

View file

@ -65,6 +65,7 @@ enum ColorType
CF_IA,
CF_CMYK,
CF_YCbCr,
CF_YCCK,
CF_BGR,
CF_BGRA,
CF_I16,
@ -326,6 +327,15 @@ struct cYCbCr
static __forceinline int Gray(const unsigned char * p) { return (R(p) * 77 + G(p) * 143 + B(p) * 36) >> 8; }
};
struct cYCCK
{
static __forceinline unsigned char R(const unsigned char* p) { auto myR = cYCbCr::R(p); return p[3] - ((myR * p[3]) >> 8); }
static __forceinline unsigned char G(const unsigned char* p) { auto myG = cYCbCr::G(p); return p[3] - ((myG * p[3]) >> 8); }
static __forceinline unsigned char B(const unsigned char* p) { auto myB = cYCbCr::B(p); return p[3] - ((myB * p[3]) >> 8); }
static __forceinline unsigned char A(const unsigned char* p, uint8_t x, uint8_t y, uint8_t z) { return 255; }
static __forceinline int Gray(const unsigned char* p) { return (R(p) * 77 + G(p) * 143 + B(p) * 36) >> 8; }
};
struct cBGR
{
static __forceinline unsigned char R(const unsigned char * p) { return p[2]; }

View file

@ -282,6 +282,7 @@ TArray<uint8_t> FJPEGTexture::CreatePalettedPixels(int conversion)
jpeg_read_header(&cinfo, TRUE);
if (!((cinfo.out_color_space == JCS_RGB && cinfo.num_components == 3) ||
(cinfo.out_color_space == JCS_CMYK && cinfo.num_components == 4) ||
(cinfo.out_color_space == JCS_YCCK && cinfo.num_components == 4) ||
(cinfo.out_color_space == JCS_YCbCr && cinfo.num_components == 3) ||
(cinfo.out_color_space == JCS_GRAYSCALE && cinfo.num_components == 1)))
{
@ -350,6 +351,24 @@ TArray<uint8_t> FJPEGTexture::CreatePalettedPixels(int conversion)
}
break;
case JCS_YCCK:
// Probably useless but since I had the formula available...
for (int x = Width; x > 0; --x)
{
double Y = in[0], Cb = in[1], Cr = in[2];
int K = in[3];
int r = clamp((int)(Y + 1.40200 * (Cr - 0x80)), 0, 255);
int g = clamp((int)(Y - 0.34414 * (Cb - 0x80) - 0.71414 * (Cr - 0x80)), 0, 255);
int b = clamp((int)(Y + 1.77200 * (Cb - 0x80)), 0, 255);
r = r - ((r * K) >> 8);
g = g - ((g * K) >> 8);
b = b - ((b * K) >> 8);
*out = ImageHelpers::RGBToPalette(doalpha, r, g, b);
out += Height;
in += 4;
}
break;
default:
// The other colorspaces were considered above and discarded,
// but GCC will complain without a default for them here.
@ -402,6 +421,7 @@ int FJPEGTexture::CopyPixels(FBitmap *bmp, int conversion)
if (!((cinfo.out_color_space == JCS_RGB && cinfo.num_components == 3) ||
(cinfo.out_color_space == JCS_CMYK && cinfo.num_components == 4) ||
(cinfo.out_color_space == JCS_YCCK && cinfo.num_components == 4) ||
(cinfo.out_color_space == JCS_YCbCr && cinfo.num_components == 3) ||
(cinfo.out_color_space == JCS_GRAYSCALE && cinfo.num_components == 1)))
{
@ -439,6 +459,11 @@ int FJPEGTexture::CopyPixels(FBitmap *bmp, int conversion)
4, cinfo.output_width * cinfo.output_components, 0, CF_CMYK);
break;
case JCS_YCCK:
bmp->CopyPixelDataRGB(0, 0, buff.Data(), cinfo.output_width, cinfo.output_height,
4, cinfo.output_width * cinfo.output_components, 0, CF_YCCK);
break;
case JCS_YCbCr:
bmp->CopyPixelDataRGB(0, 0, buff.Data(), cinfo.output_width, cinfo.output_height,
4, cinfo.output_width * cinfo.output_components, 0, CF_YCbCr);