Skip to content

Commit e20b87c

Browse files
committed
handle RGBA in windows
1 parent 8f8babf commit e20b87c

File tree

2 files changed

+111
-11
lines changed

2 files changed

+111
-11
lines changed

src/main.cpp

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,48 @@ void *load(void *args)
359359
// not webp, try jpg png etc.
360360
#if _WIN32
361361
pixeldata = wic_decode_image(imagepath.c_str(), &w, &h, &c);
362+
if (pixeldata)
363+
{
364+
// WIC channel conversion logic similar to stb_image
365+
if (c == 1)
366+
{
367+
// grayscale -> rgb
368+
unsigned char *rgbdata = (unsigned char *)malloc(w * h * 3);
369+
if (rgbdata)
370+
{
371+
for (int i = 0; i < w * h; i++)
372+
{
373+
unsigned char gray = pixeldata[i];
374+
rgbdata[i * 3 + 0] = gray; // B
375+
rgbdata[i * 3 + 1] = gray; // G
376+
rgbdata[i * 3 + 2] = gray; // R
377+
}
378+
free(pixeldata);
379+
pixeldata = rgbdata;
380+
c = 3;
381+
}
382+
}
383+
else if (c == 2)
384+
{
385+
// grayscale + alpha -> rgba
386+
unsigned char *rgbadata = (unsigned char *)malloc(w * h * 4);
387+
if (rgbadata)
388+
{
389+
for (int i = 0; i < w * h; i++)
390+
{
391+
unsigned char gray = pixeldata[i * 2];
392+
unsigned char alpha = pixeldata[i * 2 + 1];
393+
rgbadata[i * 4 + 0] = gray; // B
394+
rgbadata[i * 4 + 1] = gray; // G
395+
rgbadata[i * 4 + 2] = gray; // R
396+
rgbadata[i * 4 + 3] = alpha; // A
397+
}
398+
free(pixeldata);
399+
pixeldata = rgbadata;
400+
c = 4;
401+
}
402+
}
403+
}
362404
#else // _WIN32
363405
pixeldata = stbi_load_from_memory(filedata, length, &w, &h, &c, 0);
364406
if (pixeldata)
@@ -401,9 +443,9 @@ void *load(void *args)
401443
path_t output_filename2 = get_file_name_without_extension(ltp->output_files[i]) + PATHSTR('.') + ext;
402444
v.outpath = output_filename2;
403445
#if _WIN32
404-
fwprintf(stderr, L"ℹ️ Info: Image %s has alpha channel!\n", imagepath.c_str());
446+
fwprintf(stderr, L"ℹ️ Info: Image %s has alpha channel! Converting to RGB for JPEG output.\n", imagepath.c_str());
405447
#else // _WIN32
406-
fprintf(stderr, "ℹ️ Info: Image %s has alpha channel!\n", imagepath.c_str());
448+
fprintf(stderr, "ℹ️ Info: Image %s has alpha channel! Converting to RGB for JPEG output.\n", imagepath.c_str());
407449
#endif // _WIN32
408450
}
409451

@@ -412,9 +454,9 @@ void *load(void *args)
412454
else
413455
{
414456
#if _WIN32
415-
fwprintf(stderr, L"🚨 Error: Couldn't read the image '%s'!\n", imagepath.c_str());
457+
fwprintf(stderr, L"🚨 Error: Couldn't read the image '%s'! (channels: %d)\n", imagepath.c_str(), c);
416458
#else // _WIN32
417-
fprintf(stderr, "🚨 Error: Couldn't read the image '%s'!\n", imagepath.c_str());
459+
fprintf(stderr, "🚨 Error: Couldn't read the image '%s'! (channels: %d)\n", imagepath.c_str(), c);
418460
#endif // _WIN32
419461
}
420462
}
@@ -637,6 +679,10 @@ void *save(void *args)
637679
else if (ext == PATHSTR("jpg") || ext == PATHSTR("JPG") || ext == PATHSTR("jpeg") || ext == PATHSTR("JPEG"))
638680
{
639681
#if _WIN32
682+
if (verbose)
683+
{
684+
fwprintf(stderr, L"🔧 Debug: Saving JPEG with %d channels, size %dx%d\n", v.outimage.elempack, v.outimage.w, v.outimage.h);
685+
}
640686
success = wic_encode_jpeg_image(v.outpath.c_str(), v.outimage.w, v.outimage.h, v.outimage.elempack, v.outimage.data);
641687
#else
642688
success = stbi_write_jpg(v.outpath.c_str(), v.outimage.w, v.outimage.h, v.outimage.elempack, v.outimage.data, 100 - (int)stp->compression);

src/wic_image.h

Lines changed: 61 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,35 @@ unsigned char *wic_decode_image(const wchar_t *filepath, int *w, int *h, int *c)
5555
if (frame->GetPixelFormat(&pixel_format))
5656
goto RETURN;
5757

58-
if (!IsEqualGUID(pixel_format, GUID_WICPixelFormat32bppBGRA))
59-
pixel_format = GUID_WICPixelFormat24bppBGR;
60-
58+
// Enhanced alpha channel detection and handling
59+
BOOL has_alpha = FALSE;
6160
if (global_palette_has_alpha || frame_palette_has_alpha)
62-
pixel_format = GUID_WICPixelFormat32bppBGRA;
61+
{
62+
has_alpha = TRUE;
63+
}
64+
else
65+
{
66+
// Check if the pixel format itself has alpha
67+
if (IsEqualGUID(pixel_format, GUID_WICPixelFormat32bppBGRA) ||
68+
IsEqualGUID(pixel_format, GUID_WICPixelFormat32bppRGBA) ||
69+
IsEqualGUID(pixel_format, GUID_WICPixelFormat32bppPBGRA) ||
70+
IsEqualGUID(pixel_format, GUID_WICPixelFormat32bppPRGBA))
71+
{
72+
has_alpha = TRUE;
73+
}
74+
}
6375

64-
channels = IsEqualGUID(pixel_format, GUID_WICPixelFormat32bppBGRA) ? 4 : 3;
76+
// Choose appropriate output format based on alpha detection
77+
if (has_alpha)
78+
{
79+
pixel_format = GUID_WICPixelFormat32bppBGRA;
80+
channels = 4;
81+
}
82+
else
83+
{
84+
pixel_format = GUID_WICPixelFormat24bppBGR;
85+
channels = 3;
86+
}
6587

6688
if (converter->Initialize(frame, pixel_format, WICBitmapDitherTypeNone, 0, 0.0, WICBitmapPaletteTypeCustom))
6789
goto RETURN;
@@ -197,7 +219,38 @@ int wic_encode_image(const wchar_t *filepath, int w, int h, int c, void *bgrdata
197219

198220
int wic_encode_jpeg_image(const wchar_t *filepath, int w, int h, int c, void *bgrdata)
199221
{
200-
// assert c == 3
222+
// Convert 4-channel RGBA to 3-channel RGB for JPEG
223+
unsigned char *rgbdata = 0;
224+
int ret = 0;
225+
226+
if (c == 4)
227+
{
228+
// Convert RGBA to RGB by removing alpha channel
229+
rgbdata = (unsigned char *)malloc(w * h * 3);
230+
if (!rgbdata)
231+
return 0;
232+
233+
const unsigned char *src = (const unsigned char *)bgrdata;
234+
unsigned char *dst = rgbdata;
235+
236+
for (int i = 0; i < w * h; i++)
237+
{
238+
// Copy BGR channels, skip alpha
239+
dst[0] = src[0]; // B
240+
dst[1] = src[1]; // G
241+
dst[2] = src[2]; // R
242+
src += 4; // Skip alpha
243+
dst += 3;
244+
}
245+
246+
bgrdata = rgbdata;
247+
c = 3;
248+
}
249+
else if (c != 3)
250+
{
251+
// Invalid channel count for JPEG
252+
return 0;
253+
}
201254

202255
IWICImagingFactory *factory = 0;
203256
IWICStream *stream = 0;
@@ -207,7 +260,6 @@ int wic_encode_jpeg_image(const wchar_t *filepath, int w, int h, int c, void *bg
207260
WICPixelFormatGUID format = GUID_WICPixelFormat24bppBGR;
208261
int stride = (w * c * 8 + 7) / 8;
209262
unsigned char *data = 0;
210-
int ret = 0;
211263

212264
PROPBAG2 option = {0};
213265
option.pstrName = L"ImageQuality";
@@ -274,6 +326,8 @@ int wic_encode_jpeg_image(const wchar_t *filepath, int w, int h, int c, void *bg
274326
RETURN:
275327
if (data)
276328
free(data);
329+
if (rgbdata)
330+
free(rgbdata);
277331
if (encoder)
278332
encoder->Release();
279333
if (frame)

0 commit comments

Comments
 (0)