Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Factory:NonFree
xv
xv-more-bmp-formats.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File xv-more-bmp-formats.patch of Package xv
From e1d01328aa87af48e17947304fe5bf08a9096419 Mon Sep 17 00:00:00 2001 From: "Matthew A. Lukowicz" <matt@pancakehut> Date: Wed, 7 Feb 2024 00:08:25 -0500 Subject: [PATCH] Add support for more PC BMP formats. --- src/xvbmp.c | 203 ++++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 151 insertions(+), 52 deletions(-) --- src/xvbmp.c +++ src/xvbmp.c 2024-02-07 11:41:04.894069678 +0000 @@ -26,9 +26,13 @@ #define BI_JPEG 4 /* BMP version 5 (not yet supported) */ #define BI_PNG 5 /* BMP version 5 (not yet supported) */ -#define WIN_OS2_OLD 12 -#define WIN_NEW 40 -#define OS2_NEW 64 +#define BMPV2 12 +#define BMPV3 40 +#define MS_ADOBE_V2 52 /* FIXME: Loads with corrupt colors */ +#define MS_ADOBE_V3 56 /* FIXME: Loads with corrput colors */ +#define OS2_BMPV2 64 +#define BMPV4 108 +#define BMPV5 124 #if (defined(UINT_MAX) && UINT_MAX != 0xffffffffU) # error XV's BMP code requires 32-bit unsigned integer type, but u_int isn't @@ -36,14 +40,14 @@ static long filesize; -static int loadBMP1 PARM((FILE *, byte *, u_int, u_int)); -static int loadBMP4 PARM((FILE *, byte *, u_int, u_int, u_int)); -static int loadBMP8 PARM((FILE *, byte *, u_int, u_int, u_int)); -static int loadBMP16 PARM((FILE *, byte *, u_int, u_int, u_int *)); -static int loadBMP24 PARM((FILE *, byte *, u_int, u_int, u_int)); -static int loadBMP32 PARM((FILE *, byte *, u_int, u_int, u_int *)); -static u_int getshort PARM((FILE *)); -static u_int getint PARM((FILE *)); +static int loadBMP1 PARM((FILE *, byte *, u_int, u_int, int)); +static int loadBMP4 PARM((FILE *, byte *, u_int, u_int, u_int, int)); +static int loadBMP8 PARM((FILE *, byte *, u_int, u_int, u_int, int)); +static int loadBMP16 PARM((FILE *, byte *, u_int, u_int, u_int *, int)); +static int loadBMP24 PARM((FILE *, byte *, u_int, u_int, u_int, int)); +static int loadBMP32 PARM((FILE *, byte *, u_int, u_int, u_int *, int)); +static u_int getshort PARM((FILE *)); +static u_int getint PARM((FILE *)); static void putshort PARM((FILE *, int)); static void putint PARM((FILE *, int)); static void writeBMP1 PARM((FILE *, byte *, int, int)); @@ -62,11 +66,13 @@ int LoadBMP(fname, pinfo) /*******************************************/ { FILE *fp; - int i, c, c1, rv, bPad; - u_int bfSize, bfOffBits, biSize, biWidth, biHeight, biPlanes; + int i, c, c1, rv, bPad, rightsideup = 0; + u_int bfSize, bfOffBits, biSize, biWidth, biPlanes; u_int biBitCount, biCompression, biSizeImage, biXPelsPerMeter; u_int biYPelsPerMeter, biClrUsed, biClrImportant; + u_int npixels; u_int colormask[3]; + int biHeight; char buf[512], rgb_bits[16]; const char *cmpstr, *bname; byte *pic24, *pic8; @@ -95,7 +101,8 @@ int LoadBMP(fname, pinfo) biSize = getint(fp); - if (biSize == WIN_NEW || biSize == OS2_NEW) { + if (biSize == BMPV3 || biSize == OS2_BMPV2 ||biSize == MS_ADOBE_V2 || + biSize == MS_ADOBE_V3 || biSize == BMPV4 || biSize == BMPV5) { biWidth = getint(fp); biHeight = getint(fp); biPlanes = getshort(fp); @@ -121,6 +128,22 @@ int LoadBMP(fname, pinfo) biClrUsed = biClrImportant = 0; } + /* Height could be negative for uncompressed BMP files if data is + stored right-side-up */ + npixels = biWidth * biHeight; + if (biWidth != 0 && npixels/biWidth != biHeight && biCompression == BI_RGB) { + u_int negHeight, npixels2; + + negHeight = biHeight * -1; + npixels2 = biWidth * negHeight; + + if (npixels2/biWidth == negHeight) { + biHeight = negHeight; + npixels = npixels2; + rightsideup = 1; + } + } + if (DEBUG>1) { fprintf(stderr,"\nLoadBMP:\tbfSize=%d, bfOffBits=%d\n",bfSize,bfOffBits); fprintf(stderr,"\t\tbiSize=%d, biWidth=%d, biHeight=%d, biPlanes=%d\n", @@ -140,7 +163,6 @@ int LoadBMP(fname, pinfo) biPlanes!=1 || biCompression>BI_PNG || biWidth<=0 || biHeight<=0 || (biClrUsed && biClrUsed > (1 << biBitCount))) { - sprintf(buf, "Unsupported BMP type (%dx%d, Bits=%d, Colors=%d, Planes=%d, " "Compr=%d)", @@ -175,7 +197,7 @@ int LoadBMP(fname, pinfo) bPad = 0; - if (biSize != WIN_OS2_OLD) { + if (biSize != BMPV2) { /* skip ahead to colormap, using biSize */ c = biSize - 40; /* 40 bytes read from biSize to biClrImportant */ for (i=0; i<c; i++) @@ -191,6 +213,9 @@ int LoadBMP(fname, pinfo) bPad -= 12; } + if (biClrUsed > (1 << biBitCount)) + biClrUsed = (1 << biBitCount); + /* load up colormap, if any */ if (biBitCount == 1 || biBitCount == 4 || biBitCount == 8) { int i, cmaplen; @@ -200,7 +225,7 @@ int LoadBMP(fname, pinfo) pinfo->b[i] = getc(fp); pinfo->g[i] = getc(fp); pinfo->r[i] = getc(fp); - if (biSize != WIN_OS2_OLD) { + if (biSize != BMPV2) { getc(fp); bPad -= 4; } @@ -218,7 +243,7 @@ int LoadBMP(fname, pinfo) } } - if (biSize != WIN_OS2_OLD) { + if (biSize != BMPV2) { /* Waste any unused bytes between the colour map (if present) and the start of the actual bitmap data. */ @@ -231,21 +256,18 @@ int LoadBMP(fname, pinfo) /* create pic8 or pic24 */ if (biBitCount==16 || biBitCount==24 || biBitCount==32) { - u_int npixels = biWidth * biHeight; u_int count = 3 * npixels; if (biWidth == 0 || biHeight == 0 || npixels/biWidth != biHeight || count/3 != npixels) return (bmpError(bname, "image dimensions too large")); - pic24 = (byte *) calloc((size_t) count, (size_t) 1); + pic24 = (byte *) calloc((size_t) (count + 1), (size_t) 1); if (!pic24) return (bmpError(bname, "couldn't malloc 'pic24'")); } else { - u_int npixels = biWidth * biHeight; - if (biWidth == 0 || biHeight == 0 || npixels/biWidth != biHeight) return (bmpError(bname, "image dimensions too large")); - pic8 = (byte *) calloc((size_t) npixels, (size_t) 1); + pic8 = (byte *) calloc((size_t) (npixels + 1), (size_t) 1); if (!pic8) return(bmpError(bname, "couldn't malloc 'pic8'")); } @@ -254,23 +276,24 @@ int LoadBMP(fname, pinfo) /* load up the image */ switch (biBitCount) { case 1: - rv = loadBMP1(fp, pic8, biWidth, biHeight); + rv = loadBMP1(fp, pic8, biWidth, biHeight, rightsideup); break; case 4: - rv = loadBMP4(fp, pic8, biWidth, biHeight, biCompression); + rv = loadBMP4(fp, pic8, biWidth, biHeight, biCompression, rightsideup); break; case 8: - rv = loadBMP8(fp, pic8, biWidth, biHeight, biCompression); + rv = loadBMP8(fp, pic8, biWidth, biHeight, biCompression, rightsideup); break; case 16: rv = loadBMP16(fp, pic24, biWidth, biHeight, /* v-- BI_RGB */ - biCompression == BI_BITFIELDS? colormask : NULL); + biCompression == BI_BITFIELDS? colormask : NULL, + rightsideup); break; default: if (biBitCount == 32 && biCompression == BI_BITFIELDS) - rv = loadBMP32(fp, pic24, biWidth, biHeight, colormask); + rv = loadBMP32(fp, pic24, biWidth, biHeight, colormask, rightsideup); else /* 24 or (32 and BI_RGB) */ - rv = loadBMP24(fp, pic24, biWidth, biHeight, biBitCount); + rv = loadBMP24(fp, pic24, biWidth, biHeight, biBitCount, rightsideup); break; } @@ -314,9 +337,14 @@ int LoadBMP(fname, pinfo) pinfo->frmType = F_BMP; pinfo->colType = F_FULLCOLOR; - sprintf(pinfo->fullInfo, "%sBMP, %d bit%s per pixel%s. (%ld bytes)", - ((biSize==WIN_OS2_OLD) ? "Old OS/2 " : - (biSize==WIN_NEW) ? "Windows " : ""), + sprintf(pinfo->fullInfo, "%s, %d bit%s per pixel%s. (%ld bytes)", + ((biSize==BMPV2) ? "Windows BMP v2 " : + (biSize==BMPV3) ? "Windows BMP v3 " : + (biSize==MS_ADOBE_V2) ? "BITMAPV2INFOHEADER " : + (biSize==MS_ADOBE_V3) ? "BITMAPV3INFOHEADER " : + (biSize==OS2_BMPV2) ? "OS/2 BMP 2.0 " : + (biSize==BMPV4) ? "Windows BMP v4 " : + (biSize==BMPV5) ? "Windows BMP v5 " : ""), biBitCount, (biBitCount == 1) ? "" : "s", cmpstr, filesize); @@ -333,19 +361,31 @@ int LoadBMP(fname, pinfo) /*******************************************/ -static int loadBMP1(fp, pic8, w, h) +static int loadBMP1(fp, pic8, w, h, rightsideup) FILE *fp; byte *pic8; u_int w,h; + int rightsideup; { - int i,j,c,bitnum,padw; + int i,j,c,bitnum,padw,ibegin,iend,iinc; byte *pp = pic8 + ((h - 1) * w); size_t l = w*h; c = 0; padw = ((w + 31)/32) * 32; /* 'w', padded to be a multiple of 32 */ - for (i=h-1; i>=0 && (pp - pic8 <= l); i--) { + if (rightsideup) { + ibegin = 0; + iend = h; + iinc = 1; + } + else { + ibegin = h-1; + iend = -1; + iinc = -1; + } + + for (i = ibegin; i != iend && (pp - pic8 <= l); i += iinc) { pp = pic8 + (i * w); if ((i&0x3f)==0) WaitCursor(); for (j=bitnum=0; j<padw; j++,bitnum++) { @@ -368,12 +408,14 @@ static int loadBMP1(fp, pic8, w, h) /*******************************************/ -static int loadBMP4(fp, pic8, w, h, comp) +static int loadBMP4(fp, pic8, w, h, comp, rightsideup) FILE *fp; byte *pic8; u_int w,h,comp; + int rightsideup; { int i,j,c,c1,x,y,nybnum,padw,rv; + int begin, end, inc; byte *pp = pic8 + ((h - 1) * w); size_t l = w*h; @@ -381,9 +423,20 @@ static int loadBMP4(fp, pic8, w, h, comp c = c1 = 0; if (comp == BI_RGB) { /* read uncompressed data */ + if (rightsideup) { + begin = 0; + end = h; + inc = 1; + } + else { + begin = h-1; + end = -1; + inc = -1; + } + padw = ((w + 7)/8) * 8; /* 'w' padded to a multiple of 8pix (32 bits) */ - for (i=h-1; i>=0 && (pp - pic8 <= l); i--) { + for (i = begin; i != end && (pp - pic8 <= l); i += inc) { pp = pic8 + (i * w); if ((i&0x3f)==0) WaitCursor(); @@ -454,24 +507,37 @@ static int loadBMP4(fp, pic8, w, h, comp /*******************************************/ -static int loadBMP8(fp, pic8, w, h, comp) +static int loadBMP8(fp, pic8, w, h, comp, rightsideup) FILE *fp; byte *pic8; u_int w,h,comp; + int rightsideup; { int i,j,c,c1,padw,x,y,rv; + int begin, end, inc; byte *pp = pic8 + ((h - 1) * w); size_t l = w*h; byte *pend; rv = 0; - pend = pic8 + w * h; + pend = pic8 + l; if (comp == BI_RGB) { /* read uncompressed data */ + if (rightsideup) { + begin = 0; + end = h; + inc = 1; + } + else { + begin = h-1; + end = -1; + inc = -1; + } + padw = ((w + 3)/4) * 4; /* 'w' padded to a multiple of 4pix (32 bits) */ - for (i=h-1; i>=0 && (pp - pic8 <= l); i--) { + for (i = begin; i != end && (pp - pic8 <= l); i += inc) { pp = pic8 + (i * w); if ((i&0x3f)==0) WaitCursor(); @@ -534,12 +600,13 @@ static int loadBMP8(fp, pic8, w, h, comp /*******************************************/ -static int loadBMP16(fp, pic24, w, h, mask) +static int loadBMP16(fp, pic24, w, h, mask, rightsideup) FILE *fp; byte *pic24; u_int w, h, *mask; + int rightsideup; { - int x, y; + int x, y, ybegin, yend, yinc; byte *pp = pic24 + ((h - 1) * w * 3); size_t l = w*h*3; u_int buf, colormask[6]; @@ -611,7 +678,18 @@ static int loadBMP16(fp, pic24, w, h, ma colorbits[2], colormask[2], bitshift[2], bitshift2[2], colormask[5], bitshift[5], bitshift2[5]); - for (y = h-1; y >= 0 && (pp - pic24 <= l); y--) { + if (rightsideup) { + ybegin = 0; + yend = h; + yinc = 1; + } + else { + ybegin = h-1; + yend = -1; + yinc = -1; + } + + for (y = ybegin; y != yend && (pp - pic24 <= l); y += yinc) { pp = pic24 + (3 * w * y); if ((y&0x3f)==0) WaitCursor(); @@ -638,12 +716,13 @@ static int loadBMP16(fp, pic24, w, h, ma /*******************************************/ -static int loadBMP24(fp, pic24, w, h, bits) /* also handles 32-bit BI_RGB */ +static int loadBMP24(fp, pic24, w, h, bits, rightsideup) /* also handles 32-bit BI_RGB */ FILE *fp; byte *pic24; u_int w,h, bits; + int rightsideup; { - int i,j,padb,rv; + int i,j,padb,rv,ibegin,iend,iinc; byte *pp = pic24 + ((h - 1) * w * 3); size_t l = w*h*3; @@ -652,7 +731,18 @@ static int loadBMP24(fp, pic24, w, h, bi padb = (4 - ((w*3) % 4)) & 0x03; /* # of pad bytes to read at EOscanline */ if (bits==32) padb = 0; - for (i=h-1; i>=0; i--) { + if (rightsideup) { + ibegin = 0; + iend = h; + iinc = 1; + } + else { + ibegin = h-1; + iend = -1; + iinc = -1; + } + + for (i=ibegin; i != iend; i+=iinc) { pp = pic24 + (i * w * 3); if ((i&0x3f)==0) WaitCursor(); @@ -676,12 +766,13 @@ static int loadBMP24(fp, pic24, w, h, bi /*******************************************/ -static int loadBMP32(fp, pic24, w, h, colormask) /* 32-bit BI_BITFIELDS only */ +static int loadBMP32(fp, pic24, w, h, colormask, rightsideup) /* 32-bit BI_BITFIELDS only */ FILE *fp; byte *pic24; u_int w, h, *colormask; + int rightsideup; { - int x, y; + int x, y, ybegin, yend, yinc; byte *pp; u_int buf; int i, bit, bitshift[3], colorbits[3], bitshift2[3]; @@ -722,7 +813,18 @@ static int loadBMP32(fp, pic24, w, h, co colorbits[1], colormask[1], bitshift[1], bitshift2[1], colorbits[2], colormask[2], bitshift[2], bitshift2[2]); - for (y = h-1; y >= 0; y--) { + if (rightsideup) { + ybegin = 0; + yend = h; + yinc = 1; + } + else { + ybegin = h-1; + yend = -1; + yinc = -1; + } + + for (y = ybegin; y != yend; y += yinc) { pp = pic24 + (3 * w * y); if ((y&0x3f)==0) WaitCursor(); @@ -1078,6 +1180,3 @@ static int bmpError(fname, st) SetISTR(ISTR_WARNING,"%s: %s", fname, st); return 0; } - - -
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor