Windows: fix compiler warning [-Wstrict-aliasing]

In function ‘void innards(...)’:
src/drivers/GDI/Fl_GDI_Graphics_Driver_image.cxx:132:23:
dereferencing type-punned pointer will break strict-aliasing rules
  BITMAPINFO &bmi = *((BITMAPINFO*)bmibuffer);
                     ~^~~~~~~~~~~~~~~~~~~~~~~

Found with gcc 12 (MinGW cross compiler)

Also: use correct sizes (sizeof) rather than hardcoded values.
This commit is contained in:
Albrecht Schlosser 2024-10-31 18:38:50 +01:00
parent bdb5972504
commit 34f465add2

View File

@ -1,7 +1,7 @@
// //
// Windows image drawing code for the Fast Light Tool Kit (FLTK). // Windows image drawing code for the Fast Light Tool Kit (FLTK).
// //
// Copyright 1998-2020 by Bill Spitzak and others. // Copyright 1998-2024 by Bill Spitzak and others.
// //
// This library is free software. Distribution and use rights are outlined in // This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this // the file "COPYING" which should have been included with this file. If this
@ -128,43 +128,44 @@ static void innards(const uchar *buf, int X, int Y, int W, int H,
if (w<=0 || h<=0) return; if (w<=0 || h<=0) return;
if (buf) buf += (x-X)*delta + (y-Y)*linedelta; if (buf) buf += (x-X)*delta + (y-Y)*linedelta;
static U32 bmibuffer[256+12]; // bmibuffer: BITMAPINFOHEADER + 256 colors (RGBQUAD) + 1 (rounding effects ?)
BITMAPINFO &bmi = *((BITMAPINFO*)bmibuffer); static U32 bmibuffer[sizeof(BITMAPINFOHEADER)/4 + 257];
if (!bmi.bmiHeader.biSize) { BITMAPINFO *bmi = (BITMAPINFO*)bmibuffer;
bmi.bmiHeader.biSize = sizeof(bmi)-4; // does it use this to determine type? if (!bmi->bmiHeader.biSize) {
bmi.bmiHeader.biPlanes = 1; bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biCompression = BI_RGB; bmi->bmiHeader.biPlanes = 1;
bmi.bmiHeader.biXPelsPerMeter = 0; bmi->bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biYPelsPerMeter = 0; bmi->bmiHeader.biXPelsPerMeter = 0;
bmi.bmiHeader.biClrUsed = 0; bmi->bmiHeader.biYPelsPerMeter = 0;
bmi.bmiHeader.biClrImportant = 0; bmi->bmiHeader.biClrUsed = 0;
bmi->bmiHeader.biClrImportant = 0;
} }
#if USE_COLORMAP #if USE_COLORMAP
if (indexed) { if (indexed) {
for (short i=0; i<256; i++) { for (short i=0; i<256; i++) {
*((short*)(bmi.bmiColors)+i) = i; *((short*)(bmi->bmiColors)+i) = i;
} }
} else } else
#endif #endif
if (depth<3) { if (depth<3) {
RGBQUAD *bmi_colors = &bmi.bmiColors[0]; // suppress warning (STR #3199) RGBQUAD *bmi_colors = &(bmi->bmiColors[0]); // use pointer to suppress warning (STR #3199)
for (int i=0; i<256; i++) { for (int i=0; i<256; i++) {
bmi_colors[i].rgbBlue = (uchar)i; // bmi.bmiColors[i]... bmi_colors[i].rgbBlue = (uchar)i; // = bmi->bmiColors[i]
bmi_colors[i].rgbGreen = (uchar)i; bmi_colors[i].rgbGreen = (uchar)i;
bmi_colors[i].rgbRed = (uchar)i; bmi_colors[i].rgbRed = (uchar)i;
bmi_colors[i].rgbReserved = (uchar)0; // must be zero bmi_colors[i].rgbReserved = (uchar)0; // must be zero
} }
} }
bmi.bmiHeader.biWidth = w; bmi->bmiHeader.biWidth = w;
#if USE_COLORMAP #if USE_COLORMAP
bmi.bmiHeader.biBitCount = indexed ? 8 : depth*8; bmi->bmiHeader.biBitCount = indexed ? 8 : depth*8;
int pixelsize = indexed ? 1 : depth; int pixelsize = indexed ? 1 : depth;
#else #else
bmi.bmiHeader.biBitCount = depth*8; bmi->bmiHeader.biBitCount = depth*8;
int pixelsize = depth; int pixelsize = depth;
#endif #endif
if (depth==2) { // special case: gray with alpha if (depth==2) { // special case: gray with alpha
bmi.bmiHeader.biBitCount = 32; bmi->bmiHeader.biBitCount = 32;
pixelsize = 4; pixelsize = 4;
} }
int linesize = (pixelsize*w+3)&~3; int linesize = (pixelsize*w+3)&~3;
@ -185,7 +186,7 @@ static void innards(const uchar *buf, int X, int Y, int W, int H,
buffer = new U32[(size + 3) / 4]; buffer = new U32[(size + 3) / 4];
} }
} }
bmi.bmiHeader.biHeight = blocking; bmi->bmiHeader.biHeight = blocking;
static U32* line_buffer; static U32* line_buffer;
if (!buf) { if (!buf) {
int size = W*delta; int size = W*delta;
@ -259,7 +260,7 @@ static void innards(const uchar *buf, int X, int Y, int W, int H,
// does not do the expected job, whereas StretchDIBits does it. // does not do the expected job, whereas StretchDIBits does it.
StretchDIBits(gc, x, y+j-k, w, k, 0, 0, w, k, StretchDIBits(gc, x, y+j-k, w, k, 0, 0, w, k,
(LPSTR)((uchar*)buffer+(blocking-k)*linesize), (LPSTR)((uchar*)buffer+(blocking-k)*linesize),
&bmi, bmi,
#if USE_COLORMAP #if USE_COLORMAP
indexed ? DIB_PAL_COLORS : DIB_RGB_COLORS indexed ? DIB_PAL_COLORS : DIB_RGB_COLORS
#else #else
@ -273,7 +274,7 @@ static void innards(const uchar *buf, int X, int Y, int W, int H,
else { else {
SetDIBitsToDevice(gc, x, y+j-k, w, k, 0, 0, 0, k, SetDIBitsToDevice(gc, x, y+j-k, w, k, 0, 0, 0, k,
(LPSTR)((uchar*)buffer+(blocking-k)*linesize), (LPSTR)((uchar*)buffer+(blocking-k)*linesize),
&bmi, bmi,
#if USE_COLORMAP #if USE_COLORMAP
indexed ? DIB_PAL_COLORS : DIB_RGB_COLORS indexed ? DIB_PAL_COLORS : DIB_RGB_COLORS
#else #else