X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=image.c;h=ef0aac4e90a2f547e60b9d46e6baaa124c29b8cd;hb=32bea9b074a4ee3e82fe0bbe82005da9f2d6f418;hp=71cacb6e0b7e25168e61fb647997f5d7114474a0;hpb=e77a0ac55f772695996f145d103bd8ffd81487fd;p=xonotic%2Fdarkplaces.git diff --git a/image.c b/image.c index 71cacb6e..ef0aac4e 100644 --- a/image.c +++ b/image.c @@ -8,6 +8,14 @@ int image_width; int image_height; +void Image_CopyAlphaFromBlueBGRA(unsigned char *outpixels, const unsigned char *inpixels, int w, int h) +{ + int i, n; + n = w * h; + for(i = 0; i < n; ++i) + outpixels[4*i+3] = inpixels[4*i]; // blue channel +} + #if 1 // written by LordHavoc in a readable way, optimized by Vic, further optimized by LordHavoc (the non-special index case), readable version preserved below this void Image_CopyMux(unsigned char *outpixels, const unsigned char *inpixels, int inputwidth, int inputheight, qboolean inputflipx, qboolean inputflipy, qboolean inputflipdiagonal, int numoutputcomponents, int numinputcomponents, int *outputinputcomponentindices) @@ -26,14 +34,14 @@ void Image_CopyMux(unsigned char *outpixels, const unsigned char *inpixels, int if (inputflipdiagonal) { for (x = 0, line = inpixels + col_ofs; x < inputwidth; x++, line += col_inc) - for (y = 0, in = line + row_ofs; y < inputheight; y++, in += row_inc, outpixels += numinputcomponents) + for (y = 0, in = line + row_ofs; y < inputheight; y++, in += row_inc, outpixels += numoutputcomponents) for (c = 0; c < numoutputcomponents; c++) outpixels[c] = ((index = outputinputcomponentindices[c]) & 0x80000000) ? index : in[index]; } else { for (y = 0, line = inpixels + row_ofs; y < inputheight; y++, line += row_inc) - for (x = 0, in = line + col_ofs; x < inputwidth; x++, in += col_inc, outpixels += numinputcomponents) + for (x = 0, in = line + col_ofs; x < inputwidth; x++, in += col_inc, outpixels += numoutputcomponents) for (c = 0; c < numoutputcomponents; c++) outpixels[c] = ((index = outputinputcomponentindices[c]) & 0x80000000) ? index : in[index]; } @@ -44,14 +52,14 @@ void Image_CopyMux(unsigned char *outpixels, const unsigned char *inpixels, int if (inputflipdiagonal) { for (x = 0, line = inpixels + col_ofs; x < inputwidth; x++, line += col_inc) - for (y = 0, in = line + row_ofs; y < inputheight; y++, in += row_inc, outpixels += numinputcomponents) + for (y = 0, in = line + row_ofs; y < inputheight; y++, in += row_inc, outpixels += numoutputcomponents) for (c = 0; c < numoutputcomponents; c++) outpixels[c] = in[outputinputcomponentindices[c]]; } else { for (y = 0, line = inpixels + row_ofs; y < inputheight; y++, line += row_inc) - for (x = 0, in = line + col_ofs; x < inputwidth; x++, in += col_inc, outpixels += numinputcomponents) + for (x = 0, in = line + col_ofs; x < inputwidth; x++, in += col_inc, outpixels += numoutputcomponents) for (c = 0; c < numoutputcomponents; c++) outpixels[c] = in[outputinputcomponentindices[c]]; } @@ -248,7 +256,6 @@ unsigned char* LoadPCX_BGRA (const unsigned char *f, int filesize) else a[x++] = dataByte; } - fin += pcx.bytes_per_line - image_width; // the number of bytes per line is always forced to an even number while(x < image_width) a[x++] = 0; } @@ -268,6 +275,85 @@ unsigned char* LoadPCX_BGRA (const unsigned char *f, int filesize) return image_buffer; } +/* +============ +LoadPCX +============ +*/ +qboolean LoadPCX_QWSkin(const unsigned char *f, int filesize, unsigned char *pixels, int outwidth, int outheight) +{ + pcx_t pcx; + unsigned char *a; + const unsigned char *fin, *enddata; + int x, y, x2, dataByte, pcxwidth, pcxheight; + + if (filesize < (int)sizeof(pcx) + 768) + return false; + + image_width = outwidth; + image_height = outheight; + fin = f; + + memcpy(&pcx, fin, sizeof(pcx)); + fin += sizeof(pcx); + + // LordHavoc: big-endian support ported from QF newtree + pcx.xmax = LittleShort (pcx.xmax); + pcx.xmin = LittleShort (pcx.xmin); + pcx.ymax = LittleShort (pcx.ymax); + pcx.ymin = LittleShort (pcx.ymin); + pcx.hres = LittleShort (pcx.hres); + pcx.vres = LittleShort (pcx.vres); + pcx.bytes_per_line = LittleShort (pcx.bytes_per_line); + pcx.palette_type = LittleShort (pcx.palette_type); + + pcxwidth = pcx.xmax + 1 - pcx.xmin; + pcxheight = pcx.ymax + 1 - pcx.ymin; + if (pcx.manufacturer != 0x0a || pcx.version != 5 || pcx.encoding != 1 || pcx.bits_per_pixel != 8 || pcxwidth > 4096 || pcxheight > 4096 || pcxwidth <= 0 || pcxheight <= 0) + return false; + + enddata = f + filesize - 768; + + for (y = 0;y < outheight && fin < enddata;y++) + { + a = pixels + y * outwidth; + // pad the output with blank lines if needed + if (y >= pcxheight) + { + memset(a, 0, outwidth); + continue; + } + for (x = 0;x < pcxwidth;) + { + if (fin >= enddata) + return false; + dataByte = *fin++; + if(dataByte >= 0xC0) + { + x2 = x + (dataByte & 0x3F); + if (fin >= enddata) + return false; + if (x2 > pcxwidth) + return false; + dataByte = *fin++; + for (;x < x2;x++) + if (x < outwidth) + a[x] = dataByte; + } + else + { + if (x < outwidth) // truncate to destination width + a[x] = dataByte; + x++; + } + } + while(x < outwidth) + a[x++] = 0; + } + + return true; +} + /* ========================================================= @@ -327,14 +413,15 @@ unsigned char *LoadTGA_BGRA (const unsigned char *f, int filesize) targa_header.y_origin = f[10] + f[11] * 256; targa_header.width = image_width = f[12] + f[13] * 256; targa_header.height = image_height = f[14] + f[15] * 256; + targa_header.pixel_size = f[16]; + targa_header.attributes = f[17]; + if (image_width > 4096 || image_height > 4096 || image_width <= 0 || image_height <= 0) { Con_Print("LoadTGA: invalid size\n"); PrintTargaHeader(&targa_header); return NULL; } - targa_header.pixel_size = f[16]; - targa_header.attributes = f[17]; // advance to end of header fin = f + 18; @@ -702,6 +789,10 @@ imageformat_t imageformats_tenebrae[] = {"override/%s.png", PNG_LoadImage_BGRA}, {"override/%s.jpg", JPEG_LoadImage_BGRA}, {"override/%s.pcx", LoadPCX_BGRA}, + {"%s.tga", LoadTGA_BGRA}, + {"%s.png", PNG_LoadImage_BGRA}, + {"%s.jpg", JPEG_LoadImage_BGRA}, + {"%s.pcx", LoadPCX_BGRA}, {NULL, NULL} }; @@ -767,10 +858,10 @@ unsigned char *loadimagepixelsbgra (const char *filename, qboolean complain, qbo { fs_offset_t filesize; imageformat_t *firstformat, *format; - unsigned char *f, *data = NULL; - char basename[MAX_QPATH], name[MAX_QPATH], *c; - if (developer_memorydebug.integer) - Mem_CheckSentinelsGlobal(); + unsigned char *f, *data = NULL, *data2 = NULL; + char basename[MAX_QPATH], name[MAX_QPATH], name2[MAX_QPATH], *c; + //if (developer_memorydebug.integer) + // Mem_CheckSentinelsGlobal(); if (developer_texturelogging.integer) Log_Printf("textures.log", "%s\n", filename); Image_StripImageExtension(filename, basename, sizeof(basename)); // strip filename extensions to allow replacement by other types @@ -801,18 +892,30 @@ unsigned char *loadimagepixelsbgra (const char *filename, qboolean complain, qbo // now try all the formats in the selected list for (format = firstformat;format->formatstring;format++) { - sprintf (name, format->formatstring, basename); + dpsnprintf (name, sizeof(name), format->formatstring, basename); f = FS_LoadFile(name, tempmempool, true, &filesize); if (f) { data = format->loadfunc(f, filesize); Mem_Free(f); + if(format->loadfunc == JPEG_LoadImage_BGRA) // jpeg can't do alpha, so let's simulate it by loading another jpeg + { + dpsnprintf (name2, sizeof(name2), format->formatstring, va("%s_alpha", basename)); + f = FS_LoadFile(name2, tempmempool, true, &filesize); + if(f) + { + data2 = format->loadfunc(f, filesize); + Mem_Free(f); + Image_CopyAlphaFromBlueBGRA(data, data2, image_width, image_height); + Mem_Free(data2); + } + } if (data) { - if (developer.integer >= 10) - Con_Printf("loaded image %s (%dx%d)\n", name, image_width, image_height); - if (developer_memorydebug.integer) - Mem_CheckSentinelsGlobal(); + if (developer_loading.integer) + Con_DPrintf("loaded image %s (%dx%d)\n", name, image_width, image_height); + //if (developer_memorydebug.integer) + // Mem_CheckSentinelsGlobal(); if(allowFixtrans && r_fixtrans_auto.integer) { int n = fixtransparentpixels(data, image_width, image_height); @@ -832,10 +935,7 @@ unsigned char *loadimagepixelsbgra (const char *filename, qboolean complain, qbo return data; } else - { - if (developer.integer >= 1) - Con_DPrintf("Error loading image %s (file loaded but decode failed)\n", name); - } + Con_DPrintf("Error loading image %s (file loaded but decode failed)\n", name); } } if (complain) @@ -843,12 +943,16 @@ unsigned char *loadimagepixelsbgra (const char *filename, qboolean complain, qbo Con_Printf("Couldn't load %s using ", filename); for (format = firstformat;format->formatstring;format++) { - sprintf (name, format->formatstring, basename); + dpsnprintf (name, sizeof(name), format->formatstring, basename); Con_Printf(format == firstformat ? "\"%s\"" : (format[1].formatstring ? ", \"%s\"" : " or \"%s\".\n"), format->formatstring); } } - if (developer_memorydebug.integer) - Mem_CheckSentinelsGlobal(); + + // texture loading can take a while, so make sure we're sending keepalives + CL_KeepaliveMessage(false); + + //if (developer_memorydebug.integer) + // Mem_CheckSentinelsGlobal(); return NULL; } @@ -871,7 +975,7 @@ int fixtransparentpixels(unsigned char *data, int w, int h) int const FIXTRANS_HAS_U = 8; int const FIXTRANS_HAS_D = 16; int const FIXTRANS_FIXED = 32; - unsigned char *fixMask = Mem_Alloc(tempmempool, w * h); + unsigned char *fixMask = (unsigned char *) Mem_Alloc(tempmempool, w * h); int fixPixels = 0; int changedPixels = 0; int x, y; @@ -1015,6 +1119,7 @@ void Image_FixTransparentPixels_f(void) Con_Printf("unchanged.\n"); Mem_Free(data); } + FS_FreeSearch(search); } qboolean Image_WriteTGABGR_preflipped (const char *filename, int width, int height, const unsigned char *data, unsigned char *buffer)