X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fscreen%2Ftexture.cxx;h=6f744c35dda23fece90a776141333658d6849c97;hb=c7cbb22667c901e6107dd099e02e9506f9fbd360;hp=f306bc7629dfb8808bdf1e92016890e54b011604;hpb=dfc23c352890901dec3e69433d5efd270ba2cccc;p=simgear.git diff --git a/simgear/screen/texture.cxx b/simgear/screen/texture.cxx index f306bc76..6f744c35 100644 --- a/simgear/screen/texture.cxx +++ b/simgear/screen/texture.cxx @@ -17,8 +17,9 @@ # include #endif -#include SG_GLU_H +#include +#include #include #include "texture.hxx" @@ -48,9 +49,7 @@ SGTexture::SGTexture(unsigned int width, unsigned int height) SGTexture::~SGTexture() { - if ( texture_data ) { - delete texture_data; - } + delete[] texture_data; if ( texture_id != 0 ) { free_id(); @@ -181,8 +180,7 @@ SGTexture::read_alpha_texture(const char *name) SGTexture::ImageRec *image; int y; - if (texture_data) - delete texture_data; + delete[] texture_data; image = ImageOpen(name); if(!image) { @@ -220,12 +218,11 @@ void SGTexture::read_rgb_texture(const char *name) { GLubyte *ptr; - GLubyte *rbuf, *gbuf, *bbuf, *abuf; + GLubyte *rbuf, *gbuf, *bbuf; SGTexture::ImageRec *image; int y; - if (texture_data) - delete texture_data; + delete[] texture_data; image = ImageOpen(name); if(!image) { @@ -235,51 +232,45 @@ SGTexture::read_rgb_texture(const char *name) texture_width = image->xsize; texture_height = image->ysize; - if (image->zsize != 3 && image->zsize != 4) { + if (image->zsize < 1 || image->zsize > 4) { ImageClose(image); errstr = WRONG_COUNT; return; } - texture_data = new GLubyte[ image->xsize * image->ysize * 3 ]; num_colors = 3; + texture_data = new GLubyte[ image->xsize * image->ysize * num_colors ]; rbuf = new GLubyte[ image->xsize ]; gbuf = new GLubyte[ image->xsize ]; bbuf = new GLubyte[ image->xsize ]; - abuf = new GLubyte[ image->xsize ]; - if(!texture_data || !rbuf || !gbuf || !bbuf || !abuf) { - delete texture_data; - delete rbuf; - delete gbuf; - delete bbuf; - delete abuf; + if(!texture_data || !rbuf || !gbuf || !bbuf) { + delete[] texture_data; + delete[] rbuf; + delete[] gbuf; + delete[] bbuf; errstr = OUT_OF_MEMORY; return; } ptr = texture_data; for(y=0; yysize; y++) { - if(image->zsize == 4) { + if(image->zsize == 4 || image->zsize == 3) { ImageGetRow(image,rbuf,y,0); ImageGetRow(image,gbuf,y,1); ImageGetRow(image,bbuf,y,2); - ImageGetRow(image,abuf,y,3); // discard - rgbtorgb(rbuf,gbuf,bbuf,ptr,image->xsize); - ptr += (image->xsize * 3); } else { ImageGetRow(image,rbuf,y,0); - ImageGetRow(image,gbuf,y,1); - ImageGetRow(image,bbuf,y,2); - rgbtorgb(rbuf,gbuf,bbuf,ptr,image->xsize); - ptr += (image->xsize * 3); + memcpy(gbuf,rbuf,image->xsize); + memcpy(bbuf,rbuf,image->xsize); } + rgbtorgb(rbuf,gbuf,bbuf,ptr,image->xsize); + ptr += (image->xsize * num_colors); } ImageClose(image); - delete rbuf; - delete gbuf; - delete bbuf; - delete abuf; + delete[] rbuf; + delete[] gbuf; + delete[] bbuf; } @@ -292,8 +283,7 @@ SGTexture::read_rgba_texture(const char *name) SGTexture::ImageRec *image; int y; - if (texture_data) - delete texture_data; + delete[] texture_data; image = ImageOpen(name); if(!image) { @@ -303,52 +293,60 @@ SGTexture::read_rgba_texture(const char *name) texture_width = image->xsize; texture_height = image->ysize; - if (image->zsize != 3 && image->zsize != 4) { + if (image->zsize < 1 || image->zsize > 4) { ImageClose(image); errstr = WRONG_COUNT; return; } - texture_data = new GLubyte[ image->xsize * image->ysize * 4 ]; num_colors = 4; + texture_data = new GLubyte[ image->xsize * image->ysize * num_colors ]; rbuf = new GLubyte[ image->xsize ]; gbuf = new GLubyte[ image->xsize ]; bbuf = new GLubyte[ image->xsize ]; abuf = new GLubyte[ image->xsize ]; if(!texture_data || !rbuf || !gbuf || !bbuf || !abuf) { - delete texture_data; - delete rbuf; - delete gbuf; - delete bbuf; - delete abuf; + delete[] texture_data; + delete[] rbuf; + delete[] gbuf; + delete[] bbuf; + delete[] abuf; errstr = OUT_OF_MEMORY; return; } ptr = texture_data; - memset(abuf, 255, image->xsize); for(y=0; yysize; y++) { if(image->zsize == 4) { ImageGetRow(image,rbuf,y,0); ImageGetRow(image,gbuf,y,1); ImageGetRow(image,bbuf,y,2); ImageGetRow(image,abuf,y,3); - rgbatorgba(rbuf,gbuf,bbuf,abuf,ptr,image->xsize); - ptr += (image->xsize * 4); - } else { + } else if(image->zsize == 3) { ImageGetRow(image,rbuf,y,0); ImageGetRow(image,gbuf,y,1); ImageGetRow(image,bbuf,y,2); - rgbatorgba(rbuf,gbuf,bbuf,abuf,ptr,image->xsize); - ptr += (image->xsize * 3); + memset(abuf, 255, image->xsize); + } else if(image->zsize == 2) { + ImageGetRow(image,rbuf,y,0); + memcpy(gbuf,rbuf,image->xsize); + memcpy(bbuf,rbuf,image->xsize); + ImageGetRow(image,abuf,y,1); + } else { + ImageGetRow(image,rbuf,y,0); + memcpy(gbuf,rbuf,image->xsize); + memcpy(bbuf,rbuf,image->xsize); + memset(abuf, 255, image->xsize); } + rgbatorgba(rbuf,gbuf,bbuf,abuf,ptr,image->xsize); + ptr += (image->xsize * num_colors); } ImageClose(image); - delete rbuf; - delete gbuf; - delete bbuf; - delete abuf; + delete[] rbuf; + delete[] gbuf; + delete[] bbuf; + delete[] abuf; } void @@ -358,8 +356,7 @@ SGTexture::read_raw_texture(const char *name) SGTexture::ImageRec *image; int y; - if (texture_data) - delete texture_data; + delete[] texture_data; image = RawImageOpen(name); @@ -393,8 +390,7 @@ SGTexture::read_r8_texture(const char *name) SGTexture::ImageRec *image; int xy; - if (texture_data) - delete texture_data; + delete[] texture_data; //it wouldn't make sense to write a new function ... image = RawImageOpen(name); @@ -543,7 +539,9 @@ void SGTexture::ImageClose(SGTexture::ImageRec *image) { if (image->file) gzclose(image->file); if (file) fclose(file); - delete image->tmp; + delete[] image->tmp; + delete[] image->rowStart; + delete[] image->rowSize; delete image; } @@ -584,7 +582,7 @@ SGTexture::RawImageOpen(const char *fileName) //just allocate a pseudo value as I'm too lazy to change ImageClose()... - image->tmp = new GLubyte; + image->tmp = new GLubyte[1]; if (image->tmp == 0) { errstr = OUT_OF_MEMORY; @@ -630,14 +628,13 @@ SGTexture::ImageWriteOpen(const char *fileName) image->ysize = texture_height; image->zsize = num_colors; - fwrite(image, 1, 12, file); - - fseek(file, 512, SEEK_SET); - if (swapFlag) { ConvertShort(&image->imagic, 6); } + fwrite(image, 1, 12, file); + fseek(file, 512, SEEK_SET); + image->tmp = new GLubyte[ image->xsize * 256 ]; if (image->tmp == 0) { errstr = OUT_OF_MEMORY; @@ -654,8 +651,8 @@ SGTexture::ImageWriteOpen(const char *fileName) } image->rleEnd = 512 + (2 * x); fseek(file, 512, SEEK_SET); - fwrite(image->rowStart, 1, x, file); - fwrite(image->rowSize, 1, x, file); + fread(image->rowStart, 1, x, file); + fread(image->rowSize, 1, x, file); if (swapFlag) { ConvertUint(image->rowStart, x/(int) sizeof(unsigned)); ConvertUint((unsigned *)image->rowSize, x/(int) sizeof(int)); @@ -673,12 +670,12 @@ SGTexture::ImageGetRow(SGTexture::ImageRec *image, GLubyte *buf, int y, int z) { if ((image->type & 0xFF00) == 0x0100) { gzseek(image->file, (long) image->rowStart[y+z*image->ysize], SEEK_SET); - gzread(image->file, image->tmp, - (unsigned int)image->rowSize[y+z*image->ysize]); + int size = image->rowSize[y+z*image->ysize]; + gzread(image->file, image->tmp, size); iPtr = image->tmp; oPtr = buf; - for (;;) { + for (GLubyte *limit = iPtr + size; iPtr < limit;) { pixel = *iPtr++; count = (int)(pixel & 0x7F); if (!count) { @@ -686,10 +683,10 @@ SGTexture::ImageGetRow(SGTexture::ImageRec *image, GLubyte *buf, int y, int z) { return; } if (pixel & 0x80) { - while (count--) { + while (iPtr < limit && count--) { *oPtr++ = *iPtr++; } - } else { + } else if (iPtr < limit) { pixel = *iPtr++; while (count--) { *oPtr++ = pixel; @@ -807,6 +804,11 @@ SGTexture::make_monochrome(float contrast, GLubyte r, GLubyte g, GLubyte b) { GLubyte *rgb = get_pixel(x,y); GLubyte avg = (rgb[0] + rgb[1] + rgb[2]) / 3; + if (contrast != 1.0) { + float pixcol = -1.0 + (avg/128); + avg = 128 + int(128*pow(pixcol, contrast)); + } + ap[0] = avg*r/255; ap[1] = avg*g/255; ap[2] = avg*b/255; @@ -818,35 +820,130 @@ SGTexture::make_monochrome(float contrast, GLubyte r, GLubyte g, GLubyte b) { void SGTexture::make_grayscale(float contrast) { - if (num_colors >= 3) + if (num_colors < 3) return; - GLubyte *map = (GLubyte *)malloc (texture_width * texture_height); + int colors = (num_colors == 3) ? 1 : 2; + GLubyte *map = new GLubyte[ texture_width * texture_height * colors ]; + for (int y=0; y 1) + map[pos+1] = rgb[3]; } - free (texture_data); + delete[] texture_data; texture_data = map; - num_colors = 1; + num_colors = colors; +} + + +void +SGTexture::make_maxcolorwindow() { + GLubyte minmaxc[2] = {255, 0}; + + int pos = 0; + int max = num_colors; + if (num_colors == 2) max = 1; + if (num_colors == 4) max = 3; + while (pos < texture_width * texture_height * num_colors) { + for (int i=0; i < max; i++) { + GLubyte c = texture_data[pos+i]; + if (c < minmaxc[0]) minmaxc[0] = c; + if (c > minmaxc[1]) minmaxc[1] = c; + } + pos += num_colors; + } + + GLubyte offs = minmaxc[0]; + float factor = 255.0 / float(minmaxc[1] - minmaxc[0]); + // printf("Min: %i, Max: %i, Factor: %f\n", offs, minmaxc[1], factor); + + pos = 0; + while (pos < texture_width * texture_height * num_colors) { + for (int i=0; i < max; i++) { + texture_data[pos+i] -= offs; + texture_data[pos+i] = int(factor * texture_data[pos+i]); + } + pos += num_colors; + } } void SGTexture::make_normalmap(float brightness, float contrast) { make_grayscale(contrast); + make_maxcolorwindow(); + + int colors = (num_colors == 1) ? 3 : 4; + bool alpha = (colors > 3); + int tsize = texture_width * texture_height * colors; + GLubyte *map = new GLubyte[ tsize ]; + + int mpos = 0, dpos = 0; + for (int y=0; y 1) + map[mpos+1] = texture_data[dpos+1]; } - free (texture_data); + delete[] texture_data; texture_data = map; - num_colors = 3; + num_colors = colors; } +