Mercurial > hg > dmlib
changeset 1360:fcaf04cb0830
Make image palette remapping use a destination image instead of doing remapping on the source image.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Fri, 22 Sep 2017 15:58:32 +0300 |
parents | 28fe5b0925dc |
children | 00f47a678482 |
files | tools/gfxconv.c |
diffstat | 1 files changed, 67 insertions(+), 48 deletions(-) [+] |
line wrap: on
line diff
--- a/tools/gfxconv.c Wed Aug 30 03:35:52 2017 +0300 +++ b/tools/gfxconv.c Fri Sep 22 15:58:32 2017 +0300 @@ -869,15 +869,22 @@ } -int dmRemapImageColors(DMImage *image) +int dmRemapImageColors(DMImage **pdst, const DMImage *src) { - DMColor *npal = dmCalloc(image->ncolors, sizeof(DMColor)); - int *mapping = dmMalloc(image->ncolors * sizeof(int)); - BOOL *mapped = dmMalloc(image->ncolors * sizeof(BOOL)); - BOOL *used = dmMalloc(image->ncolors * sizeof(BOOL)); + DMColor *npal = dmCalloc(src->ncolors, sizeof(DMColor)); + int *mapping = dmMalloc(src->ncolors * sizeof(int)); + BOOL *mapped = dmMalloc(src->ncolors * sizeof(BOOL)); + BOOL *used = dmMalloc(src->ncolors * sizeof(BOOL)); int n, index, xc, yc, ncolors; + DMImage *dst; - dmMsg(1, "Remapping %d output image colors of %d colors.\n", optNRemapTable, image->ncolors); + if ((dst = *pdst = dmImageAlloc(src->width, src->height, src->format, src->bpp)) == NULL) + { + return dmError(DMERR_MALLOC, + "Could not allocate memory for remapped image.\n"); + } + + dmMsg(1, "Remapping %d output image colors of %d colors.\n", optNRemapTable, src->ncolors); if (npal == NULL || mapping == NULL || mapped == NULL || used == NULL) { @@ -885,7 +892,7 @@ "Could not allocate memory for reused palette.\n"); } - for (index = 0; index < image->ncolors; index++) + for (index = 0; index < src->ncolors; index++) { mapping[index] = -1; mapped[index] = used[index] = FALSE; @@ -893,13 +900,13 @@ // Find used colors dmMsg(2, "Scanning image for used colors...\n"); - for (ncolors = yc = 0; yc < image->height; yc++) + for (ncolors = yc = 0; yc < src->height; yc++) { - Uint8 *dp = image->data + image->pitch * yc; - for (xc = 0; xc < image->width; xc++) + const Uint8 *dp = src->data + src->pitch * yc; + for (xc = 0; xc < src->width; xc++) { Uint8 col = dp[xc]; - if (col < image->ncolors && !used[col]) + if (col < src->ncolors && !used[col]) { used[col] = TRUE; ncolors++; @@ -915,9 +922,9 @@ if (map->triplet) { BOOL found = FALSE; - for (n = 0; n < image->ncolors; n++) + for (n = 0; n < src->ncolors; n++) { - if (dmCompareColor(&(image->pal[n]), &(map->color), map->alpha)) + if (dmCompareColor(&(src->pal[n]), &(map->color), map->alpha)) { dmMsg(3, "RGBA match #%02x%02x%02x%02x: %d -> %d\n", map->color.r, map->color.g, map->color.b, map->color.a, @@ -952,10 +959,10 @@ if (optRemapRemove) { dmMsg(2, "Removing unused colors.\n"); - for (index = 0; index < image->ncolors; index++) + for (index = 0; index < src->ncolors; index++) if (mapping[index] < 0 && used[index]) { - for (n = 0; n < image->ncolors; n++) + for (n = 0; n < src->ncolors; n++) if (!mapped[n]) { mapping[index] = n; @@ -966,10 +973,10 @@ } else { - for (index = 0; index < image->ncolors; index++) + for (index = 0; index < src->ncolors; index++) if (mapping[index] < 0) { - for (n = 0; n < image->ncolors; n++) + for (n = 0; n < src->ncolors; n++) if (!mapped[n]) { mapping[index] = n; @@ -981,30 +988,31 @@ // Calculate final number of palette colors ncolors = 0; - for (index = 0; index < image->ncolors; index++) + for (index = 0; index < src->ncolors; index++) { if (mapping[index] + 1 > ncolors) ncolors = mapping[index] + 1; } // Copy palette entries - for (index = 0; index < image->ncolors; index++) + for (index = 0; index < src->ncolors; index++) { if (mapping[index] >= 0) { - memcpy(&npal[mapping[index]], &(image->pal[index]), sizeof(DMColor)); + memcpy(&npal[mapping[index]], &(src->pal[index]), sizeof(DMColor)); } } // Remap image dmMsg(1, "Remapping image to %d colors...\n", ncolors); - for (yc = 0; yc < image->height; yc++) + for (yc = 0; yc < src->height; yc++) { - Uint8 *dp = image->data + image->pitch * yc; - for (xc = 0; xc < image->width; xc++) + Uint8 *sp = src->data + src->pitch * yc; + Uint8 *dp = dst->data + dst->pitch * yc; + for (xc = 0; xc < src->width; xc++) { - Uint8 col = dp[xc]; - if (col < image->ncolors && mapping[col] >= 0 && mapping[col] < image->ncolors) + Uint8 col = sp[xc]; + if (col < src->ncolors && mapping[col] >= 0 && mapping[col] < src->ncolors) dp[xc] = mapping[col]; else dp[xc] = 0; @@ -1012,9 +1020,8 @@ } // Set new palette, free memory - dmFree(image->pal); - image->pal = npal; - image->ncolors = ncolors; + dst->pal = npal; + dst->ncolors = ncolors; dmFree(mapping); dmFree(mapped); @@ -1093,23 +1100,29 @@ } -int dmWriteImage(const char *filename, DMImage *image, DMImageConvSpec *spec, int iformat, BOOL info) +int dmWriteImage(const char *filename, DMImage *pimage, DMImageConvSpec *spec, int iformat, BOOL info) { + int res = DMERR_OK; + if (info) { dmMsg(1, "Outputting %s image %d x %d -> %d x %d [%d x %d]\n", dmImageFormatList[iformat].fext, - image->width, image->height, - image->width * spec->scaleX, image->height * spec->scaleY, + pimage->width, pimage->height, + pimage->width * spec->scaleX, pimage->height * spec->scaleY, spec->scaleX, spec->scaleY); } // Perform color remapping + DMImage *image = pimage; + BOOL allocated = FALSE; if (optRemapColors) { int res; - if ((res = dmRemapImageColors(image)) != DMERR_OK) + if ((res = dmRemapImageColors(&image, pimage)) != DMERR_OK) return res; + + allocated = TRUE; } switch (iformat) @@ -1118,44 +1131,44 @@ case IMGFMT_PNG: spec->format = spec->paletted ? DM_IFMT_PALETTE : DM_IFMT_RGBA; dmOutputImageBitFormat(spec->format, info); - return dmWritePNGImage(filename, image, spec); + res = dmWritePNGImage(filename, image, spec); + break; #endif case IMGFMT_PPM: spec->format = DM_IFMT_RGB; dmOutputImageBitFormat(spec->format, info); - return dmWritePPMImage(filename, image, spec); + res = dmWritePPMImage(filename, image, spec); + break; case IMGFMT_PCX: spec->format = spec->paletted ? DM_IFMT_PALETTE : DM_IFMT_RGB; dmOutputImageBitFormat(spec->format, info); - return dmWritePCXImage(filename, image, spec); + res = dmWritePCXImage(filename, image, spec); + break; case IMGFMT_RAW: case IMGFMT_ARAW: { + // Open data file for writing FILE *fp; - char *dataFilename; - - // Form data file filename - dataFilename = dm_strdup_fext(filename, "%s.inc"); - if (dataFilename == NULL) - return DMERR_MALLOC; - - // Open data file for writing + char * dataFilename = dm_strdup_fext(filename, "%s.inc"); if ((fp = fopen(dataFilename, "w")) == NULL) - dmErrorMsg("Could not create '%s'.\n", dataFilename); + { + res = dmError(DMERR_FOPEN, + "Could not create '%s'.\n", dataFilename); + goto err; + } dmFree(dataFilename); if (fp != NULL) { // Strip extension - int i; char *palID = dm_strdup_fext(filename, "img_%s"); // Replace any non-alphanumerics - for (i = 0; palID[i]; i++) + for (int i = 0; palID[i]; i++) { if (isalnum(palID[i])) palID[i] = tolower(palID[i]); @@ -1204,13 +1217,19 @@ spec->nplanes, spec->planar ? "planar/interleaved" : "non-interleaved"); } - return dmWriteRAWImage(filename, image, spec); + res = dmWriteRAWImage(filename, image, spec); } break; default: - return DMERR_INVALID_DATA; + res = DMERR_INVALID_DATA; } + +err: + if (allocated) + dmImageFree(image); + + return res; }