Mercurial > hg > dmlib
diff tools/libgfx.c @ 2094:4276b8c0fef0
Revamp how the DMImage palette system and color formats work, as preparation
for future work on supporting non-indexed/paletted images. It is still messy.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Tue, 05 Mar 2019 09:56:47 +0200 |
parents | d17512dbb4ef |
children | 80786a28caf0 |
line wrap: on
line diff
--- a/tools/libgfx.c Thu Feb 28 12:32:07 2019 +0200 +++ b/tools/libgfx.c Tue Mar 05 09:56:47 2019 +0200 @@ -91,7 +91,7 @@ } -BOOL dmCompareColor(const DMColor *c1, const DMColor *c2, BOOL alpha) +BOOL dmCompareColor(const DMColor *c1, const DMColor *c2, const BOOL alpha) { if (c1->r == c2->r && c1->g == c2->g && @@ -133,7 +133,6 @@ img->bpp = (bpp <= 0) ? dmImageGetBitsPerPixel(format) : bpp; img->pitch = (width * img->bpp) / 8; img->size = img->pitch * img->height; - img->ctransp = -1; img->aspect = -1; if ((img->data = dmMalloc(img->size)) == NULL) @@ -151,63 +150,164 @@ if (img != NULL) { if (!img->constpal) - { - dmFree(img->pal); - } + dmPaletteFree(img->pal); + dmFree(img->data); dmFree(img); } } -BOOL dmPaletteAlloc(DMColor **ppal, int ncolors, int ctransp) +int dmPaletteAlloc(DMPalette **ppal, const int ncolors, const int ctransp) { + DMPalette *pal; if (ppal == NULL) - return FALSE; + return DMERR_NULLPTR; + + *ppal = NULL; + + // Allocate palette struct + if ((pal = dmMalloc0(sizeof(DMPalette))) == NULL) + return DMERR_MALLOC; + + pal->ncolors = ncolors; + pal->ctransp = ctransp; // Allocate desired amount of palette - if ((*ppal = dmCalloc(ncolors, sizeof(DMColor))) == NULL) - return FALSE; + if ((pal->colors = dmCalloc(pal->ncolors, sizeof(DMColor))) == NULL) + { + dmFree(pal); + return DMERR_MALLOC; + } // Set alpha values to max, except for transparent color - for (int i = 0; i < ncolors; i++) + for (int i = 0; i < pal->ncolors; i++) { - (*ppal)[i].a = (i == ctransp) ? 0x00 : 0xff; + pal->colors[i].a = (i == pal->ctransp) ? 0x00 : 0xff; } - return TRUE; + *ppal = pal; + + return DMERR_OK; } -BOOL dmImagePaletteAlloc(DMImage *img, int ncolors, int ctransp) +int dmPaletteResize(DMPalette **ppal, const int ncolors) +{ + DMPalette *pal; + + if (ppal == NULL) + return DMERR_NULLPTR; + + if (ncolors <= 0 || ncolors > 256) + return DMERR_INVALID_ARGS; + + if (*ppal == NULL) + return dmPaletteAlloc(ppal, ncolors, -1); + + pal = *ppal; + + if (pal->ncolors == ncolors) + return DMERR_OK; + + if ((pal->colors = dmRealloc(pal->colors, sizeof(DMColor) * ncolors)) == NULL) + return DMERR_MALLOC; + + if (ncolors - pal->ncolors > 0) + memset(&(pal->colors[pal->ncolors]), 0, sizeof(DMColor) * (ncolors - pal->ncolors)); + + return DMERR_OK; +} + + +int dmPaletteCopy(DMPalette **pdst, const DMPalette *src) { - if (img == NULL) - return FALSE; - - img->ncolors = ncolors; - img->ctransp = ctransp; - img->constpal = FALSE; - - return dmPaletteAlloc(&(img->pal), ncolors, ctransp); + DMPalette *pal; + if (pdst == NULL) + return DMERR_NULLPTR; + + *pdst = NULL; + + // Allocate palette struct + if ((pal = dmMalloc(sizeof(DMPalette))) == NULL) + return DMERR_MALLOC; + + memcpy(pal, src, sizeof(DMPalette)); + + // Allocate desired amount of palette + if ((pal->colors = dmCalloc(pal->ncolors, sizeof(DMColor))) == NULL) + { + dmFree(pal); + return DMERR_MALLOC; + } + + memcpy(pal->colors, src->colors, sizeof(DMColor) * pal->ncolors); + *pdst = pal; + + return DMERR_OK; } -static BOOL dmPaletteReadData(DMResource *fp, DMColor *pal, int ncolors) +void dmPaletteFree(DMPalette *pal) { + if (pal != NULL) + { + dmFree(pal->colors); + dmFree(pal); + } +} + + +static int dmPaletteReadData(DMResource *fp, DMPalette *pal, int ncolors) +{ + if (pal->ncolors < ncolors) + return DMERR_INVALID_ARGS; + for (int i = 0; i < ncolors; i++) { Uint8 colR, colG, colB; if (!dmf_read_byte(fp, &colR) || !dmf_read_byte(fp, &colG) || !dmf_read_byte(fp, &colB)) - return FALSE; - - pal[i].r = colR; - pal[i].g = colG; - pal[i].b = colB; + return DMERR_FREAD; + + pal->colors[i].r = colR; + pal->colors[i].g = colG; + pal->colors[i].b = colB; } - return TRUE; + return DMERR_OK; +} + + +static int dmPaletteWriteData(DMResource *fp, const DMPalette *pal, const int ncolors, const int npad) +{ + int i; + + if (pal == NULL || fp == NULL) + return DMERR_NULLPTR; + + if (pal->ncolors < ncolors) + return DMERR_INVALID_ARGS; + + for (i = 0; i < ncolors; i++) + { + DMColor *col = &pal->colors[i]; + if (!dmf_write_byte(fp, col->r) || + !dmf_write_byte(fp, col->g) || + !dmf_write_byte(fp, col->b)) + return DMERR_FWRITE; + } + + for (; i < npad; i++) + { + if (!dmf_write_byte(fp, 0) || + !dmf_write_byte(fp, 0) || + !dmf_write_byte(fp, 0)) + return DMERR_FWRITE; + } + + return DMERR_OK; } @@ -236,71 +336,143 @@ *ptr3 = ptr2 + rowWidth, *ptr4 = ptr3 + rowWidth; - for (x = 0; x < img->width; x++) + if (img->format == DM_COLFMT_PALETTE || + img->format == DM_COLFMT_GRAYSCALE) { - Uint8 c = img->data[(y * img->pitch) + (x * img->bpp) / 8], - qr, qg, qb, qa; - + for (x = 0; x < img->width; x++) + { + Uint8 c = img->data[(y * img->pitch) + (x * img->bpp) / 8], + qr, qg, qb, qa; + + if (c >= img->pal->ncolors) + { + res = DMERR_INVALID_DATA; + goto done; + } + + switch (spec->format) + { + case DM_COLFMT_PALETTE: + case DM_COLFMT_GRAYSCALE: + for (xscale = 0; xscale < spec->scaleX; xscale++) + *ptr1++ = c; + break; + + case DM_COLFMT_RGBA: + qr = img->pal->colors[c].r; + qg = img->pal->colors[c].g; + qb = img->pal->colors[c].b; + qa = img->pal->colors[c].a; + + if (spec->planar) + { + for (xscale = 0; xscale < spec->scaleX; xscale++) + { + *ptr1++ = qr; + *ptr2++ = qg; + *ptr3++ = qb; + *ptr4++ = qa; + } + } + else + { + for (xscale = 0; xscale < spec->scaleX; xscale++) + { + *ptr1++ = qr; + *ptr1++ = qg; + *ptr1++ = qb; + *ptr1++ = qa; + } + } + break; + + case DM_COLFMT_RGB: + qr = img->pal->colors[c].r; + qg = img->pal->colors[c].g; + qb = img->pal->colors[c].b; + + if (spec->planar) + { + for (xscale = 0; xscale < spec->scaleX; xscale++) + { + *ptr1++ = qr; + *ptr2++ = qg; + *ptr3++ = qb; + } + } + else + { + for (xscale = 0; xscale < spec->scaleX; xscale++) + { + *ptr1++ = qr; + *ptr1++ = qg; + *ptr1++ = qb; + } + } + break; + + default: + res = DMERR_NOT_SUPPORTED; + goto done; + } + } + } + else + if (img->format == DM_COLFMT_RGB || + img->format == DM_COLFMT_RGBA) + { + Uint8 *sp = img->data + (y * img->pitch); + + for (x = 0; x < img->width; x++, sp += img->bpp / 8) switch (spec->format) { - case DM_COLFMT_PALETTE: - case DM_COLFMT_GRAYSCALE: - for (xscale = 0; xscale < spec->scaleX; xscale++) - *ptr1++ = c; - break; - - case DM_COLFMT_RGBA: - qr = img->pal[c].r; - qg = img->pal[c].g; - qb = img->pal[c].b; - qa = img->pal[c].a; - + case DM_COLFMT_RGBA: if (spec->planar) { for (xscale = 0; xscale < spec->scaleX; xscale++) { - *ptr1++ = qr; - *ptr2++ = qg; - *ptr3++ = qb; - *ptr4++ = qa; + *ptr1++ = sp[0]; + *ptr2++ = sp[1]; + *ptr3++ = sp[2]; + *ptr4++ = sp[3]; } } else { for (xscale = 0; xscale < spec->scaleX; xscale++) { - *ptr1++ = qr; - *ptr1++ = qg; - *ptr1++ = qb; - *ptr1++ = qa; + *ptr1++ = sp[0]; + *ptr1++ = sp[1]; + *ptr1++ = sp[2]; + *ptr1++ = sp[3]; } } break; case DM_COLFMT_RGB: - qr = img->pal[c].r; - qg = img->pal[c].g; - qb = img->pal[c].b; - if (spec->planar) { for (xscale = 0; xscale < spec->scaleX; xscale++) { - *ptr1++ = qr; - *ptr2++ = qg; - *ptr3++ = qb; + *ptr1++ = sp[0]; + *ptr2++ = sp[1]; + *ptr3++ = sp[2]; } } else { for (xscale = 0; xscale < spec->scaleX; xscale++) { - *ptr1++ = qr; - *ptr1++ = qg; - *ptr1++ = qb; + *ptr1++ = sp[0]; + *ptr1++ = sp[1]; + *ptr1++ = sp[2]; } } break; + + default: + res = DMERR_NOT_SUPPORTED; + goto done; } } @@ -337,18 +509,18 @@ if (dmfprintf(fp, "%s_ncolors: dw.w %d\n" "%s_palette:\n", - prefix, img->ncolors, + prefix, img->pal->ncolors, prefix) < 0) return dmferror(fp); for (int i = 0; i < (1 << spec->nplanes); i++) { Uint32 color; - if (i < img->ncolors) + if (i < img->pal->ncolors) { - color = (DMCOL(img->pal[i].r) << 8) | - (DMCOL(img->pal[i].g) << 4) | - (DMCOL(img->pal[i].b)); + color = (DMCOL(img->pal->colors[i].r) << 8) | + (DMCOL(img->pal->colors[i].g) << 4) | + (DMCOL(img->pal->colors[i].b)); } else color = 0; @@ -584,7 +756,7 @@ case '5': itype = DM_COLFMT_GRAYSCALE; break; default: res = dmError(DMERR_NOT_SUPPORTED, - "PPM: Unsupported PPM/PGM subtype.\n"); + "PPM: Unsupported PPM/PNM/PGM subtype.\n"); goto error; } @@ -595,6 +767,9 @@ goto error; } + dmMsg(2, "PPM: %d x %d, type=%d\n", + width, height, itype); + if ((*pimg = img = dmImageAlloc(width, height, itype, -1)) == NULL) { res = dmError(DMERR_MALLOC, @@ -602,7 +777,7 @@ goto error; } - if (dmf_read_str(fp, img->data, img->size)) + if (!dmf_read_str(fp, img->data, img->size)) { res = dmError(DMERR_FREAD, "PPM: Could not read image data.\n"); @@ -755,14 +930,14 @@ dmMemset(palette, 0, PNG_MAX_PALETTE_LENGTH * sizeof(png_color)); - for (int i = 0; i < img->ncolors; i++) + for (int i = 0; i < img->pal->ncolors; i++) { - palette[i].red = img->pal[i].r; - palette[i].green = img->pal[i].g; - palette[i].blue = img->pal[i].b; + palette[i].red = img->pal->colors[i].r; + palette[i].green = img->pal->colors[i].g; + palette[i].blue = img->pal->colors[i].b; } - png_set_PLTE(png_ptr, info_ptr, palette, img->ncolors); + png_set_PLTE(png_ptr, info_ptr, palette, img->pal->ncolors); png_free(png_ptr, palette); } @@ -802,8 +977,7 @@ png_bytep *row_pointers = NULL; png_bytep trans = NULL; png_uint_32 width, height, res_x = 0, res_y = 0; - int i, itype, bit_depth, color_type, ncolors, ntrans, unit_type; - int res = DMERR_OK; + int res, itype, bit_depth, color_type, ncolors, ntrans, unit_type; DMImage *img; // Create PNG structures @@ -911,7 +1085,7 @@ if ((row_pointers = png_malloc(png_ptr, height * sizeof(png_bytep))) == NULL) goto error; - for (i = 0; i < img->height; i++) + for (int i = 0; i < img->height; i++) row_pointers[i] = img->data + (i * img->pitch); png_read_image(png_ptr, row_pointers); @@ -927,17 +1101,14 @@ { dmMsg(2, "PNG: Palette of %d colors found.\n", ncolors); - if (!dmImagePaletteAlloc(img, ncolors, -1)) - { - res = DMERR_MALLOC; + if ((res = dmPaletteAlloc(&(img->pal), ncolors, -1)) != DMERR_OK) goto error; - } - - for (i = 0; i < img->ncolors; i++) + + for (int i = 0; i < img->pal->ncolors; i++) { - img->pal[i].r = palette[i].red; - img->pal[i].g = palette[i].green; - img->pal[i].b = palette[i].blue; + img->pal->colors[i].r = palette[i].red; + img->pal->colors[i].g = palette[i].green; + img->pal->colors[i].b = palette[i].blue; } } @@ -945,15 +1116,17 @@ if (trans != NULL && ntrans > 0) { dmMsg(2, "PNG: %d transparent colors.\n", ntrans); - for (i = 0; i < img->ncolors && i < ntrans; i++) + for (int i = 0; i < img->pal->ncolors && i < ntrans; i++) { - img->pal[i].a = trans[i]; - if (img->ctransp < 0 && trans[i] == 0) - img->ctransp = i; + img->pal->colors[i].a = trans[i]; + if (img->pal->ctransp < 0 && trans[i] == 0) + img->pal->ctransp = i; } } } + res = DMERR_OK; + error: if (png_ptr != NULL && info_ptr != NULL) png_destroy_read_struct(&png_ptr, &info_ptr, NULL); @@ -1105,7 +1278,6 @@ return DMERR_FWRITE; } - return DMERR_OK; } @@ -1145,12 +1317,12 @@ if (spec.format == DM_COLFMT_PALETTE || spec.format == DM_COLFMT_GRAYSCALE) { - const int ncolors = img->ncolors > DMPCX_PAL_COLORS ? DMPCX_PAL_COLORS : img->ncolors; + const int ncolors = img->pal->ncolors > DMPCX_PAL_COLORS ? DMPCX_PAL_COLORS : img->pal->ncolors; for (int i = 0; i < ncolors; i++) { - hdr.colorMap[i].r = img->pal[i].r; - hdr.colorMap[i].g = img->pal[i].g; - hdr.colorMap[i].b = img->pal[i].b; + hdr.colorMap[i].r = img->pal->colors[i].r; + hdr.colorMap[i].g = img->pal->colors[i].g; + hdr.colorMap[i].b = img->pal->colors[i].b; } } hdr.manufacturer = 10; @@ -1246,34 +1418,15 @@ if (spec.format == DM_COLFMT_PALETTE || spec.format == DM_COLFMT_GRAYSCALE) { - int i; - dmMsg(2, "PCX: Writing palette of %d active entries.\n", img->ncolors); + dmMsg(2, "PCX: Writing palette of %d active entries.\n", img->pal->ncolors); dmf_write_byte(pcx.fp, 0x0C); - for (i = 0; i < img->ncolors; i++) + if ((res = dmPaletteWriteData(fp, img->pal, img->pal->ncolors, 256)) != DMERR_OK) { - if (!dmf_write_byte(pcx.fp, img->pal[i].r) || - !dmf_write_byte(pcx.fp, img->pal[i].g) || - !dmf_write_byte(pcx.fp, img->pal[i].b)) - { - res = dmError(DMERR_FWRITE, - "PCX: Could not write palette data.\n"); - goto error; - } - } - - // Pad the palette, if necessary - for (; i < 256; i++) - { - if (!dmf_write_byte(pcx.fp, 0) || - !dmf_write_byte(pcx.fp, 0) || - !dmf_write_byte(pcx.fp, 0)) - { - res = dmError(DMERR_FWRITE, - "PCX: Could not write palette data.\n"); - goto error; - } + res = dmError(DMERR_FWRITE, + "PCX: Could not write palette data.\n"); + goto error; } } @@ -1472,9 +1625,7 @@ // Decode bitplanes switch (hdr.bitsPerPlane) { - case 32: case 24: - case 16: case 8: { // Actually bytes and bits per plane per pixel .. @@ -1533,9 +1684,9 @@ ncolors = 256; } - if (!dmImagePaletteAlloc(img, ncolors, -1)) + if ((res = dmPaletteAlloc(&(img->pal), ncolors, -1)) != DMERR_OK) { - res = dmError(DMERR_MALLOC, + res = dmError(res, "PCX: Could not allocate palette data!\n"); goto error; } @@ -1544,23 +1695,25 @@ { // Okay, attempt to read the palette data dmMsg(2, "PCX: Reading palette of %d colors\n", ncolors); - if (!dmPaletteReadData(fp, img->pal, ncolors)) + if ((res = dmPaletteReadData(fp, img->pal, ncolors)) != DMERR_OK) { - res = dmError(DMERR_FREAD, - "PCX: Error reading palette.\n"); + dmErrorMsg("PCX: Error reading palette.\n"); goto error; } } else { + const int nmax = img->pal->ncolors > DMPCX_PAL_COLORS ? DMPCX_PAL_COLORS : img->pal->ncolors; + // If the extra palette is not available, copy the colors from // the header palette to our internal palette structure. - dmMsg(2, "PCX: Initializing palette from header of %d colors\n", ncolors); - for (int i = 0; i < (img->ncolors > DMPCX_PAL_COLORS ? DMPCX_PAL_COLORS : img->ncolors); i++) + dmMsg(2, "PCX: Initializing palette from header of %d colors (%d)\n", ncolors, nmax); + + for (int i = 0; i < nmax; i++) { - img->pal[i].r = hdr.colorMap[i].r; - img->pal[i].g = hdr.colorMap[i].g; - img->pal[i].b = hdr.colorMap[i].b; + img->pal->colors[i].r = hdr.colorMap[i].r; + img->pal->colors[i].g = hdr.colorMap[i].g; + img->pal->colors[i].b = hdr.colorMap[i].b; } } } @@ -1626,7 +1779,7 @@ DMIFFBMHD bmhd; Uint32 camg; int ncolors; - DMColor *pal; + DMPalette *pal; Uint32 idsig; char *idstr; } DMIFF; @@ -1896,7 +2049,7 @@ // Black out any pixels with mask bit 0 if (!data) - dp[xc] = img->ctransp < 0 ? 0 : img->ctransp; + dp[xc] = img->pal->ctransp < 0 ? 0 : img->pal->ctransp; } } } @@ -2036,16 +2189,16 @@ // Read palette if (iff.ncolors > 0) { - if (!dmPaletteAlloc(&iff.pal, iff.ncolors, - (iff.bmhd.masking == IFF_MASK_TRANSP) ? iff.bmhd.transp : -1)) + if ((res = dmPaletteAlloc(&iff.pal, iff.ncolors, + (iff.bmhd.masking == IFF_MASK_TRANSP) ? iff.bmhd.transp : -1)) != DMERR_OK) { - return dmError(DMERR_MALLOC, - "IFF: Could not allocate palette data.\n"); + dmErrorMsg("IFF: Could not allocate palette data.\n"); + return res; } - if (!dmPaletteReadData(fp, iff.pal, iff.ncolors)) + if ((res = dmPaletteReadData(fp, iff.pal, iff.ncolors)) != DMERR_OK) { - return dmError(DMERR_FREAD, - "IFF: Error reading CMAP.\n"); + dmErrorMsg("IFF: Error reading CMAP.\n"); + return res; } } @@ -2129,7 +2282,7 @@ if (*pimg != NULL && (*pimg)->format == DM_COLFMT_PALETTE) { // Check that we DO have a palette .. - if (iff.pal == NULL || iff.ncolors == 0) + if (iff.pal == NULL || iff.pal->ncolors == 0) { return dmError(DMERR_INVALID_DATA, "IFF: A paletted/indexed color image with no CMAP. Bailing out.\n"); @@ -2138,7 +2291,7 @@ // If halfbrite is used, duplicate the palette if (iff.camg & IFF_CAMG_HALFBRITE) { - void *ptmp; + int ncolors = iff.ncolors; if (iff.idsig != IFF_ID_ILBM) { dmErrorMsg("IFF: Non-planar PBM file with Halfbrite enabled! This might not work.\n"); @@ -2150,25 +2303,21 @@ "IFF: Halfbrite enabled, but ncolors > 128.\n"); } - if ((ptmp = dmRealloc(iff.pal, sizeof(DMColor) * iff.ncolors * 2)) == NULL) + if ((res = dmPaletteResize(&iff.pal, ncolors * 2)) != DMERR_OK) { - dmFree(iff.pal); - iff.pal = NULL; - return DMERR_MALLOC; + dmPaletteFree(iff.pal); + return res; } - else - iff.pal = ptmp; - - for (int i = 0; i < iff.ncolors; i++) + + for (int i = 0; i < ncolors; i++) { - int i2 = iff.ncolors + i; - iff.pal[i2].r = iff.pal[i].r / 2; - iff.pal[i2].g = iff.pal[i].g / 2; - iff.pal[i2].b = iff.pal[i].b / 2; + int i2 = ncolors + i; + iff.pal->colors[i2].r = iff.pal->colors[i].r / 2; + iff.pal->colors[i2].g = iff.pal->colors[i].g / 2; + iff.pal->colors[i2].b = iff.pal->colors[i].b / 2; } } - (*pimg)->ncolors = iff.ncolors; (*pimg)->pal = iff.pal; } @@ -2384,8 +2533,8 @@ iff.bmhd.yasp = 1; iff.camg = 0; // XXX TODO: when/if HAM support - iff.bmhd.masking = (img->ctransp < 0) ? IFF_MASK_NONE : spec->mask; - iff.bmhd.transp = (img->ctransp >= 0 && spec->mask == IFF_MASK_TRANSP) ? img->ctransp : 0xffff; + iff.bmhd.masking = (img->pal && img->pal->ctransp < 0) ? IFF_MASK_NONE : spec->mask; + iff.bmhd.transp = (img->pal && img->pal->ctransp >= 0 && spec->mask == IFF_MASK_TRANSP) ? img->pal->ctransp : 0xffff; iff.bmhd.nplanes = (iff.idsig == IFF_ID_PBM && spec->nplanes < 8) ? 8 : spec->nplanes; // Apparently ACBM can't/should not use compression .. even though @@ -2436,29 +2585,23 @@ // // CMAP // - if (img->ncolors > 0 && spec->format == DM_COLFMT_PALETTE) + if (img->pal->ncolors > 0 && spec->format == DM_COLFMT_PALETTE) { if ((res = dmWriteIFFChunkHdr(fp, &iff.chCMAP, IFF_ID_CMAP)) != DMERR_OK) goto out; - for (int i = 0; i < img->ncolors; i++) + if ((res = dmPaletteWriteData(fp, img->pal, img->pal->ncolors, -1)) != DMERR_OK) { - DMColor *col = &img->pal[i]; - if (!dmf_write_byte(fp, col->r) || - !dmf_write_byte(fp, col->g) || - !dmf_write_byte(fp, col->b)) - { - res = dmError(DMERR_FWRITE, - "IFF: Could not write CMAP palette entry #%d.\n", i); - goto out; - } + res = dmError(DMERR_FWRITE, + "IFF: Could not write CMAP palette.\n"); + goto out; } if ((res = dmWriteIFFChunkFinish(fp, &iff.chCMAP)) != DMERR_OK) goto out; dmMsg(2, "IFF: CMAP %d entries (%d bytes)\n", - img->ncolors, iff.chCMAP.size); + img->pal->ncolors, iff.chCMAP.size); } // @@ -2556,7 +2699,7 @@ dmMemset(buf, 0, bufLen); for (int xc = 0; xc < img->width * spec->scaleX; xc++) - buf[xc / 8] |= (sp[xc / spec->scaleX] == img->ctransp) << (7 - (xc & 7)); + buf[xc / 8] |= (sp[xc / spec->scaleX] == img->pal->ctransp) << (7 - (xc & 7)); if (!dmIFFWriteOneRow(fp, &iff, buf, bufLen)) {