imgtool now exports pngs as 8bit when appropriate, and imports them again without losing fullbright info.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5856 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
466dac47f4
commit
01d1ca73c1
2 changed files with 70 additions and 12 deletions
|
@ -1370,6 +1370,8 @@ static void (PNGAPI *qpng_set_filler) PNGARG((png_structp png_ptr, png_uint_32 f
|
||||||
static void (PNGAPI *qpng_set_palette_to_rgb) PNGARG((png_structp png_ptr)) PSTATIC(png_set_palette_to_rgb);
|
static void (PNGAPI *qpng_set_palette_to_rgb) PNGARG((png_structp png_ptr)) PSTATIC(png_set_palette_to_rgb);
|
||||||
static png_uint_32 (PNGAPI *qpng_get_IHDR) PNGARG((png_const_structrp png_ptr, png_const_inforp info_ptr, png_uint_32 *width, png_uint_32 *height,
|
static png_uint_32 (PNGAPI *qpng_get_IHDR) PNGARG((png_const_structrp png_ptr, png_const_inforp info_ptr, png_uint_32 *width, png_uint_32 *height,
|
||||||
int *bit_depth, int *color_type, int *interlace_method, int *compression_method, int *filter_method)) PSTATIC(png_get_IHDR);
|
int *bit_depth, int *color_type, int *interlace_method, int *compression_method, int *filter_method)) PSTATIC(png_get_IHDR);
|
||||||
|
static png_uint_32 (PNGAPI *qpng_get_PLTE) PNGARG((png_const_structrp png_ptr, png_inforp info_ptr, png_colorp *palette, int *num_palette)) PSTATIC(png_get_PLTE);
|
||||||
|
|
||||||
static void (PNGAPI *qpng_read_info) PNGARG((png_structp png_ptr, png_infop info_ptr)) PSTATIC(png_read_info);
|
static void (PNGAPI *qpng_read_info) PNGARG((png_structp png_ptr, png_infop info_ptr)) PSTATIC(png_read_info);
|
||||||
static void (PNGAPI *qpng_set_sig_bytes) PNGARG((png_structp png_ptr, int num_bytes)) PSTATIC(png_set_sig_bytes);
|
static void (PNGAPI *qpng_set_sig_bytes) PNGARG((png_structp png_ptr, int num_bytes)) PSTATIC(png_set_sig_bytes);
|
||||||
static void (PNGAPI *qpng_set_read_fn) PNGARG((png_structp png_ptr, png_voidp io_ptr, png_rw_ptr read_data_fn)) PSTATIC(png_set_read_fn);
|
static void (PNGAPI *qpng_set_read_fn) PNGARG((png_structp png_ptr, png_voidp io_ptr, png_rw_ptr read_data_fn)) PSTATIC(png_set_read_fn);
|
||||||
|
@ -1386,6 +1388,8 @@ static void (PNGAPI *qpng_set_text) PNGARG((png_const_structrp png_ptr, png_info
|
||||||
#endif
|
#endif
|
||||||
static void (PNGAPI *qpng_set_IHDR) PNGARG((png_const_structrp png_ptr, png_infop info_ptr, png_uint_32 width, png_uint_32 height,
|
static void (PNGAPI *qpng_set_IHDR) PNGARG((png_const_structrp png_ptr, png_infop info_ptr, png_uint_32 width, png_uint_32 height,
|
||||||
int bit_depth, int color_type, int interlace_method, int compression_method, int filter_method)) PSTATIC(png_set_IHDR);
|
int bit_depth, int color_type, int interlace_method, int compression_method, int filter_method)) PSTATIC(png_set_IHDR);
|
||||||
|
//static void png_set_PLTE(void);
|
||||||
|
static void (PNGAPI *qpng_set_PLTE) PNGARG((png_structrp png_ptr, png_inforp info_ptr, png_const_colorp palette, int num_palette)) PSTATIC(png_set_PLTE);
|
||||||
static void (PNGAPI *qpng_set_compression_level) PNGARG((png_structrp png_ptr, int level)) PSTATIC(png_set_compression_level);
|
static void (PNGAPI *qpng_set_compression_level) PNGARG((png_structrp png_ptr, int level)) PSTATIC(png_set_compression_level);
|
||||||
static void (PNGAPI *qpng_init_io) PNGARG((png_structp png_ptr, png_FILE_p fp)) PSTATIC(png_init_io);
|
static void (PNGAPI *qpng_init_io) PNGARG((png_structp png_ptr, png_FILE_p fp)) PSTATIC(png_init_io);
|
||||||
static png_voidp (PNGAPI *qpng_get_io_ptr) PNGARG((png_const_structrp png_ptr)) PSTATIC(png_get_io_ptr);
|
static png_voidp (PNGAPI *qpng_get_io_ptr) PNGARG((png_const_structrp png_ptr)) PSTATIC(png_get_io_ptr);
|
||||||
|
@ -1422,6 +1426,7 @@ qboolean LibPNG_Init(void)
|
||||||
{(void **) &qpng_set_filler, "png_set_filler"},
|
{(void **) &qpng_set_filler, "png_set_filler"},
|
||||||
{(void **) &qpng_set_palette_to_rgb, "png_set_palette_to_rgb"},
|
{(void **) &qpng_set_palette_to_rgb, "png_set_palette_to_rgb"},
|
||||||
{(void **) &qpng_get_IHDR, "png_get_IHDR"},
|
{(void **) &qpng_get_IHDR, "png_get_IHDR"},
|
||||||
|
{(void **) &qpng_get_PLTE, "png_get_PLTE"},
|
||||||
{(void **) &qpng_read_info, "png_read_info"},
|
{(void **) &qpng_read_info, "png_read_info"},
|
||||||
{(void **) &qpng_set_sig_bytes, "png_set_sig_bytes"},
|
{(void **) &qpng_set_sig_bytes, "png_set_sig_bytes"},
|
||||||
{(void **) &qpng_set_read_fn, "png_set_read_fn"},
|
{(void **) &qpng_set_read_fn, "png_set_read_fn"},
|
||||||
|
@ -1437,6 +1442,7 @@ qboolean LibPNG_Init(void)
|
||||||
{(void **) &qpng_write_image, "png_write_image"},
|
{(void **) &qpng_write_image, "png_write_image"},
|
||||||
{(void **) &qpng_write_info, "png_write_info"},
|
{(void **) &qpng_write_info, "png_write_info"},
|
||||||
{(void **) &qpng_set_IHDR, "png_set_IHDR"},
|
{(void **) &qpng_set_IHDR, "png_set_IHDR"},
|
||||||
|
{(void **) &qpng_set_PLTE, "png_set_PLTE"},
|
||||||
{(void **) &qpng_set_compression_level, "png_set_compression_level"},
|
{(void **) &qpng_set_compression_level, "png_set_compression_level"},
|
||||||
{(void **) &qpng_init_io, "png_init_io"},
|
{(void **) &qpng_init_io, "png_init_io"},
|
||||||
{(void **) &qpng_get_io_ptr, "png_get_io_ptr"},
|
{(void **) &qpng_get_io_ptr, "png_get_io_ptr"},
|
||||||
|
@ -1591,13 +1597,33 @@ error:
|
||||||
*height = pngheight;
|
*height = pngheight;
|
||||||
|
|
||||||
if (colortype == PNG_COLOR_TYPE_PALETTE)
|
if (colortype == PNG_COLOR_TYPE_PALETTE)
|
||||||
|
{
|
||||||
|
int numpal = 0;
|
||||||
|
png_colorp pal = NULL;
|
||||||
|
if (bitdepth==8 && format)
|
||||||
|
qpng_get_PLTE(png, pnginfo, &pal, &numpal);
|
||||||
|
if (numpal == 256)
|
||||||
|
{
|
||||||
|
for (numpal = 0; numpal < 256; numpal++)
|
||||||
|
{
|
||||||
|
if (pal[numpal].red == host_basepal[numpal*3+0] &&
|
||||||
|
pal[numpal].green == host_basepal[numpal*3+1] &&
|
||||||
|
pal[numpal].blue == host_basepal[numpal*3+2])
|
||||||
|
continue;
|
||||||
|
else
|
||||||
|
break; //bum
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (numpal != 256)
|
||||||
{
|
{
|
||||||
qpng_set_palette_to_rgb(png);
|
qpng_set_palette_to_rgb(png);
|
||||||
qpng_set_filler(png, ~0u, PNG_FILLER_AFTER);
|
qpng_set_filler(png, ~0u, PNG_FILLER_AFTER);
|
||||||
|
colortype = PNG_COLOR_TYPE_RGB;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (colortype == PNG_COLOR_TYPE_GRAY && bitdepth < 8)
|
if (colortype == PNG_COLOR_TYPE_GRAY && bitdepth < 8)
|
||||||
{
|
{ //don't handle small greyscale formats
|
||||||
#if PNG_LIBPNG_VER > 10400
|
#if PNG_LIBPNG_VER > 10400
|
||||||
qpng_set_expand_gray_1_2_4_to_8(png);
|
qpng_set_expand_gray_1_2_4_to_8(png);
|
||||||
#else
|
#else
|
||||||
|
@ -1629,7 +1655,9 @@ error:
|
||||||
channels = qpng_get_channels(png, pnginfo);
|
channels = qpng_get_channels(png, pnginfo);
|
||||||
bitdepth = qpng_get_bit_depth(png, pnginfo);
|
bitdepth = qpng_get_bit_depth(png, pnginfo);
|
||||||
|
|
||||||
if (bitdepth == 8 && channels == 4)
|
if (colortype == PNG_COLOR_TYPE_PALETTE)
|
||||||
|
*format = PTI_P8;
|
||||||
|
else if (bitdepth == 8 && channels == 4)
|
||||||
{
|
{
|
||||||
if (format)
|
if (format)
|
||||||
{
|
{
|
||||||
|
@ -1766,6 +1794,12 @@ int Image_WritePNG (const char *filename, enum fs_relative fsroot, int compressi
|
||||||
bgr = false;
|
bgr = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PTI_P8:
|
||||||
|
havepad = false;
|
||||||
|
colourtype = PNG_COLOR_TYPE_PALETTE;
|
||||||
|
chanbits = 8;
|
||||||
|
bgr = false;
|
||||||
|
break;
|
||||||
case PTI_L8:
|
case PTI_L8:
|
||||||
havepad = false;
|
havepad = false;
|
||||||
colourtype = PNG_COLOR_TYPE_GRAY;
|
colourtype = PNG_COLOR_TYPE_GRAY;
|
||||||
|
@ -1852,6 +1886,18 @@ err:
|
||||||
qpng_set_bgr(png_ptr);
|
qpng_set_bgr(png_ptr);
|
||||||
qpng_set_IHDR(png_ptr, info_ptr, outwidth, height, chanbits, colourtype, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
|
qpng_set_IHDR(png_ptr, info_ptr, outwidth, height, chanbits, colourtype, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
|
||||||
|
|
||||||
|
if (colourtype == PNG_COLOR_TYPE_PALETTE)
|
||||||
|
{
|
||||||
|
png_color pal[256];
|
||||||
|
for (i = 0; i < countof(pal); i++) {
|
||||||
|
pal[i].red = host_basepal[i*3+0];
|
||||||
|
pal[i].green = host_basepal[i*3+1];
|
||||||
|
pal[i].blue = host_basepal[i*3+2];
|
||||||
|
}
|
||||||
|
qpng_set_PLTE(png_ptr, info_ptr, pal, countof(pal));
|
||||||
|
//png_set_tRNS
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(PNG_TEXT_SUPPORTED) && defined(PNG_ITXT_COMPRESSION_NONE)
|
#if defined(PNG_TEXT_SUPPORTED) && defined(PNG_ITXT_COMPRESSION_NONE)
|
||||||
if (writemetadata)
|
if (writemetadata)
|
||||||
{
|
{
|
||||||
|
@ -3254,6 +3300,7 @@ static qbyte *ReadICOFile(const char *fname, qbyte *buf, int length, int *width,
|
||||||
#endif
|
#endif
|
||||||
if ((ret = ReadRawBMPFile(indata, insize, width, height, 0)))
|
if ((ret = ReadRawBMPFile(indata, insize, width, height, 0)))
|
||||||
{
|
{
|
||||||
|
if (fmt)
|
||||||
*fmt = PTI_RGBA8;
|
*fmt = PTI_RGBA8;
|
||||||
TRACE(("dbg: Read32BitImageFile: icon bmp\n"));
|
TRACE(("dbg: Read32BitImageFile: icon bmp\n"));
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -4358,6 +4405,8 @@ static qbyte *ReadXCFFile(const qbyte *filedata, size_t len, const char *fname,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!format && ctx.outformat != PTI_RGBA8)
|
||||||
|
return NULL; //caller insists on rgba8 :(
|
||||||
XCF_ReadHeaderProperties(&ctx);
|
XCF_ReadHeaderProperties(&ctx);
|
||||||
while((offs=XCF_ReadOffset(&ctx)))
|
while((offs=XCF_ReadOffset(&ctx)))
|
||||||
{
|
{
|
||||||
|
@ -4369,6 +4418,7 @@ static qbyte *ReadXCFFile(const qbyte *filedata, size_t len, const char *fname,
|
||||||
//without any layers, its fully transparent
|
//without any layers, its fully transparent
|
||||||
Image_BlockSizeForEncoding(ctx.outformat, &bb,&bw,&bh,&bd); //just for the bb...
|
Image_BlockSizeForEncoding(ctx.outformat, &bb,&bw,&bh,&bd); //just for the bb...
|
||||||
ctx.flat = Z_Malloc(ctx.width*ctx.height*bb);
|
ctx.flat = Z_Malloc(ctx.width*ctx.height*bb);
|
||||||
|
if (format)
|
||||||
*format = ctx.outformat;
|
*format = ctx.outformat;
|
||||||
*width = ctx.width;
|
*width = ctx.width;
|
||||||
*height = ctx.height;
|
*height = ctx.height;
|
||||||
|
@ -7390,7 +7440,7 @@ qbyte *ReadRawImageFile(qbyte *buf, int len, int *width, int *height, uploadfmt_
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len > 6 && buf[0]==0&&buf[1]==0 && buf[2]==1&&buf[3]==0 && (data = ReadICOFile(fname, buf, len, width, height, format)))
|
if (len > 6 && buf[0]==0&&buf[1]==0 && buf[2]==1&&buf[3]==0 && (data = ReadICOFile(fname, buf, len, width, height, force_rgba8?NULL:format)))
|
||||||
{
|
{
|
||||||
TRACE(("dbg: ReadRawImageFile: ico\n"));
|
TRACE(("dbg: ReadRawImageFile: ico\n"));
|
||||||
return data;
|
return data;
|
||||||
|
@ -7410,7 +7460,7 @@ qbyte *ReadRawImageFile(qbyte *buf, int len, int *width, int *height, uploadfmt_
|
||||||
return data;
|
return data;
|
||||||
#endif
|
#endif
|
||||||
#ifdef IMAGEFMT_XCF
|
#ifdef IMAGEFMT_XCF
|
||||||
if (len > 9 && !strncmp(buf, "gimp xcf ", 9) && (data = ReadXCFFile(buf, len, fname, width, height, format)))
|
if (len > 9 && !strncmp(buf, "gimp xcf ", 9) && (data = ReadXCFFile(buf, len, fname, width, height, force_rgba8?NULL:format)))
|
||||||
return data;
|
return data;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -12181,13 +12231,18 @@ void Image_ChangeFormat(struct pendingtextureinfo *mips, qboolean *allowedformat
|
||||||
static void Image_ChangeFormatFlags(struct pendingtextureinfo *mips, unsigned int flags, uploadfmt_t origfmt, const char *imagename)
|
static void Image_ChangeFormatFlags(struct pendingtextureinfo *mips, unsigned int flags, uploadfmt_t origfmt, const char *imagename)
|
||||||
{
|
{
|
||||||
if (flags & IF_PALETTIZE)
|
if (flags & IF_PALETTIZE)
|
||||||
{
|
{ //paletizing things
|
||||||
qboolean p8only[PTI_MAX] = {0};
|
qboolean p8only[PTI_MAX] = {0};
|
||||||
p8only[PTI_P8] = true;
|
p8only[PTI_P8] = true;
|
||||||
Image_ChangeFormat(mips, p8only, origfmt, imagename);
|
Image_ChangeFormat(mips, p8only, origfmt, imagename);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{ //don't allow r8-as-indexes if its fed as an input. it won't make sense unless its explicit.
|
||||||
|
qboolean p8 = sh_config.texfmt[PTI_P8];
|
||||||
|
sh_config.texfmt[PTI_P8] = false;
|
||||||
Image_ChangeFormat(mips, sh_config.texfmt, origfmt, imagename);
|
Image_ChangeFormat(mips, sh_config.texfmt, origfmt, imagename);
|
||||||
|
sh_config.texfmt[PTI_P8] = p8;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//operates in place...
|
//operates in place...
|
||||||
|
|
|
@ -1155,7 +1155,7 @@ static void ImgTool_Convert(struct opts_s *args, struct pendingtextureinfo *in,
|
||||||
(k == PTI_RGBA8) || (k == PTI_RGBX8) ||
|
(k == PTI_RGBA8) || (k == PTI_RGBX8) ||
|
||||||
(k == PTI_BGRA8) || (k == PTI_BGRX8) ||
|
(k == PTI_BGRA8) || (k == PTI_BGRX8) ||
|
||||||
(k == PTI_LLLA8) || (k == PTI_LLLX8) ||
|
(k == PTI_LLLA8) || (k == PTI_LLLX8) ||
|
||||||
(k == PTI_RGBA16) ||
|
(k == PTI_RGBA16) || (k == PTI_P8) ||
|
||||||
(k == PTI_L8) || (k == PTI_L8A8) ||
|
(k == PTI_L8) || (k == PTI_L8A8) ||
|
||||||
/*(k == PTI_L16) ||*/
|
/*(k == PTI_L16) ||*/
|
||||||
(k == PTI_BGR8) || (k == PTI_BGR8) ||
|
(k == PTI_BGR8) || (k == PTI_BGR8) ||
|
||||||
|
@ -2777,6 +2777,7 @@ struct sdlwindow_s
|
||||||
{
|
{
|
||||||
char *name;
|
char *name;
|
||||||
size_t w, h;
|
size_t w, h;
|
||||||
|
uploadfmt_t fmt;
|
||||||
SDL_Texture *t;
|
SDL_Texture *t;
|
||||||
} *tex;
|
} *tex;
|
||||||
};
|
};
|
||||||
|
@ -2902,9 +2903,9 @@ static void SDLL_Change(struct sdlwindow_s *wc, size_t newshown)
|
||||||
char title[512];
|
char title[512];
|
||||||
wc->texshown = newshown;
|
wc->texshown = newshown;
|
||||||
if (wc->texcount==1)
|
if (wc->texcount==1)
|
||||||
snprintf(title, sizeof(title), "%s", wc->tex[wc->texshown].name);
|
snprintf(title, sizeof(title), "%s %s", wc->tex[wc->texshown].name, Image_FormatName(wc->tex[wc->texshown].fmt));
|
||||||
else
|
else
|
||||||
snprintf(title, sizeof(title), "[%u/%u] %s", 1+(unsigned int)newshown, (unsigned int)wc->texcount, wc->tex[wc->texshown].name);
|
snprintf(title, sizeof(title), "[%u/%u] %s %s", 1+(unsigned int)newshown, (unsigned int)wc->texcount, wc->tex[wc->texshown].name, Image_FormatName(wc->tex[wc->texshown].fmt));
|
||||||
sdl.SetWindowTitle(wc->w, title);
|
sdl.SetWindowTitle(wc->w, title);
|
||||||
|
|
||||||
w = wc->tex[wc->texshown].w * wc->scale;
|
w = wc->tex[wc->texshown].w * wc->scale;
|
||||||
|
@ -3004,6 +3005,7 @@ static void ImgTool_View(const char *inname, struct pendingtextureinfo *in)
|
||||||
qboolean outformats[PTI_MAX] = {false};
|
qboolean outformats[PTI_MAX] = {false};
|
||||||
struct sdlwindow_s *wc;
|
struct sdlwindow_s *wc;
|
||||||
SDL_Event ev;
|
SDL_Event ev;
|
||||||
|
uploadfmt_t origencoding = in->encoding;
|
||||||
|
|
||||||
if (in->mipcount < 1 || in->mip[0].width <= 0 || in->mip[0].height <= 0)
|
if (in->mipcount < 1 || in->mip[0].width <= 0 || in->mip[0].height <= 0)
|
||||||
return;
|
return;
|
||||||
|
@ -3116,6 +3118,7 @@ static void ImgTool_View(const char *inname, struct pendingtextureinfo *in)
|
||||||
wc->tex[wc->texcount].name = Z_StrDup(inname);
|
wc->tex[wc->texcount].name = Z_StrDup(inname);
|
||||||
wc->tex[wc->texcount].w = in->mip[0].width;
|
wc->tex[wc->texcount].w = in->mip[0].width;
|
||||||
wc->tex[wc->texcount].h = in->mip[0].height;
|
wc->tex[wc->texcount].h = in->mip[0].height;
|
||||||
|
wc->tex[wc->texcount].fmt = origencoding;
|
||||||
wc->tex[wc->texcount].t = sdl.CreateTexture(wc->r, sdlfmt, SDL_TEXTUREACCESS_STATIC, in->mip[0].width, in->mip[0].height); //which needs a texture...
|
wc->tex[wc->texcount].t = sdl.CreateTexture(wc->r, sdlfmt, SDL_TEXTUREACCESS_STATIC, in->mip[0].width, in->mip[0].height); //which needs a texture...
|
||||||
if (wc->tex[wc->texcount].t)
|
if (wc->tex[wc->texcount].t)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue