X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=image.c;h=ef0aac4e90a2f547e60b9d46e6baaa124c29b8cd;hb=a905dab9d17e8f0805bc2afe64336db892d33972;hp=2a2245152adeaf4d22ea9a0bc30216c1d000883e;hpb=f87cf4e9590a353b5253b5bf098ec4450d49a965;p=xonotic%2Fdarkplaces.git diff --git a/image.c b/image.c index 2a224515..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; +} + /* ========================================================= @@ -772,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 @@ -812,12 +898,24 @@ unsigned char *loadimagepixelsbgra (const char *filename, qboolean complain, qbo { 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); @@ -849,8 +947,12 @@ unsigned char *loadimagepixelsbgra (const char *filename, qboolean complain, qbo 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; } @@ -873,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; @@ -1017,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)