void Slider::SetColour(Colour col1, Colour col2) { pixel pix[2] = {PIXRGB(col1.Red, col1.Green, col1.Blue), PIXRGB(col2.Red, col2.Green, col2.Blue)}; float fl[2] = {0.0f, 1.0f}; if(bgGradient) free(bgGradient); this->col1 = col1; this->col2 = col2; bgGradient = (unsigned char*)Graphics::GenerateGradient(pix, fl, 2, Size.X-7); }
pixel *Graphics::render_packed_rgb(void *image, int width, int height, int cmp_size) { unsigned char *tmp; pixel *res; int i; tmp = (unsigned char *)malloc(width*height*3); if (!tmp) return NULL; res = (pixel *)malloc(width*height*PIXELSIZE); if (!res) { free(tmp); return NULL; } i = width*height*3; if (BZ2_bzBuffToBuffDecompress((char *)tmp, (unsigned *)&i, (char *)image, cmp_size, 0, 0)) { free(res); free(tmp); return NULL; } for (i=0; i<width*height; i++) res[i] = PIXRGB(tmp[3*i], tmp[3*i+1], tmp[3*i+2]); free(tmp); return res; }
pixel *Graphics::rescale_img(pixel *src, int sw, int sh, int *qw, int *qh, int f) { int i,j,x,y,w,h,r,g,b,c; pixel p, *q; w = (sw+f-1)/f; h = (sh+f-1)/f; q = (pixel *)malloc(w*h*PIXELSIZE); for (y=0; y<h; y++) for (x=0; x<w; x++) { r = g = b = c = 0; for (j=0; j<f; j++) for (i=0; i<f; i++) if (x*f+i<sw && y*f+j<sh) { p = src[(y*f+j)*sw + (x*f+i)]; if (p) { r += PIXR(p); g += PIXG(p); b += PIXB(p); c ++; } } if (c>1) { r = (r+c/2)/c; g = (g+c/2)/c; b = (b+c/2)/c; } q[y*w+x] = PIXRGB(r, g, b); } *qw = w; *qh = h; return q; }
pixel *Graphics::resample_img(pixel *src, int sw, int sh, int rw, int rh) { #ifdef HIGH_QUALITY_RESAMPLE unsigned char * source = (unsigned char*)src; int sourceWidth = sw, sourceHeight = sh; int resultWidth = rw, resultHeight = rh; int sourcePitch = sourceWidth*PIXELSIZE, resultPitch = resultWidth*PIXELSIZE; // Filter scale - values < 1.0 cause aliasing, but create sharper looking mips. const float filter_scale = 0.75f; const char* pFilter = "lanczos12"; Resampler * resamplers[PIXELCHANNELS]; float * samples[PIXELCHANNELS]; //Resampler for each colour channel resamplers[0] = new Resampler(sourceWidth, sourceHeight, resultWidth, resultHeight, Resampler::BOUNDARY_CLAMP, 0.0f, 1.0f, pFilter, NULL, NULL, filter_scale, filter_scale); samples[0] = new float[sourceWidth]; for (int i = 1; i < PIXELCHANNELS; i++) { resamplers[i] = new Resampler(sourceWidth, sourceHeight, resultWidth, resultHeight, Resampler::BOUNDARY_CLAMP, 0.0f, 1.0f, pFilter, resamplers[0]->get_clist_x(), resamplers[0]->get_clist_y(), filter_scale, filter_scale); samples[i] = new float[sourceWidth]; } unsigned char * resultImage = new unsigned char[resultHeight * resultPitch]; std::fill(resultImage, resultImage + (resultHeight*resultPitch), 0); //Resample time int resultY = 0; for (int sourceY = 0; sourceY < sourceHeight; sourceY++) { unsigned char * sourcePixel = &source[sourceY * sourcePitch]; //Move pixel components into channel samples for (int c = 0; c < PIXELCHANNELS; c++) { for (int x = 0; x < sourceWidth; x++) { samples[c][x] = sourcePixel[(x*PIXELSIZE)+c] * (1.0f/255.0f); } } //Put channel sample data into resampler for (int c = 0; c < PIXELCHANNELS; c++) { if (!resamplers[c]->put_line(&samples[c][0])) { printf("Out of memory!\n"); return NULL; } } //Perform resample and Copy components from resampler result samples to image buffer for ( ; ; ) { int comp_index; for (comp_index = 0; comp_index < PIXELCHANNELS; comp_index++) { const float* resultSamples = resamplers[comp_index]->get_line(); if (!resultSamples) break; unsigned char * resultPixel = &resultImage[(resultY * resultPitch) + comp_index]; for (int x = 0; x < resultWidth; x++) { int c = (int)(255.0f * resultSamples[x] + .5f); if (c < 0) c = 0; else if (c > 255) c = 255; *resultPixel = (unsigned char)c; resultPixel += PIXELSIZE; } } if (comp_index < PIXELCHANNELS) break; resultY++; } } //Clean up for(int i = 0; i < PIXELCHANNELS; i++) { delete resamplers[i]; delete[] samples[i]; } return (pixel*)resultImage; #else #ifdef DEBUG std::cout << "Resampling " << sw << "x" << sh << " to " << rw << "x" << rh << std::endl; #endif bool stairstep = false; if(rw < sw || rh < sh) { float fx = (float)(((float)sw)/((float)rw)); float fy = (float)(((float)sh)/((float)rh)); int fxint, fyint; double fxintp_t, fyintp_t; float fxf = modf(fx, &fxintp_t), fyf = modf(fy, &fyintp_t); fxint = fxintp_t; fyint = fyintp_t; if(((fxint & (fxint-1)) == 0 && fxf < 0.1f) || ((fyint & (fyint-1)) == 0 && fyf < 0.1f)) stairstep = true; #ifdef DEBUG if(stairstep) std::cout << "Downsampling by " << fx << "x" << fy << " using stairstepping" << std::endl; else std::cout << "Downsampling by " << fx << "x" << fy << " without stairstepping" << std::endl; #endif } int y, x, fxceil, fyceil; //int i,j,x,y,w,h,r,g,b,c; pixel *q = NULL; if(rw == sw && rh == sh){ //Don't resample q = new pixel[rw*rh]; std::copy(src, src+(rw*rh), q); } else if(!stairstep) { float fx, fy, fyc, fxc; double intp; pixel tr, tl, br, bl; q = new pixel[rw*rh]; //Bilinear interpolation for upscaling for (y=0; y<rh; y++) for (x=0; x<rw; x++) { fx = ((float)x)*((float)sw)/((float)rw); fy = ((float)y)*((float)sh)/((float)rh); fxc = modf(fx, &intp); fyc = modf(fy, &intp); fxceil = (int)ceil(fx); fyceil = (int)ceil(fy); if (fxceil>=sw) fxceil = sw-1; if (fyceil>=sh) fyceil = sh-1; tr = src[sw*(int)floor(fy)+fxceil]; tl = src[sw*(int)floor(fy)+(int)floor(fx)]; br = src[sw*fyceil+fxceil]; bl = src[sw*fyceil+(int)floor(fx)]; q[rw*y+x] = PIXRGB( (int)(((((float)PIXR(tl))*(1.0f-fxc))+(((float)PIXR(tr))*(fxc)))*(1.0f-fyc) + ((((float)PIXR(bl))*(1.0f-fxc))+(((float)PIXR(br))*(fxc)))*(fyc)), (int)(((((float)PIXG(tl))*(1.0f-fxc))+(((float)PIXG(tr))*(fxc)))*(1.0f-fyc) + ((((float)PIXG(bl))*(1.0f-fxc))+(((float)PIXG(br))*(fxc)))*(fyc)), (int)(((((float)PIXB(tl))*(1.0f-fxc))+(((float)PIXB(tr))*(fxc)))*(1.0f-fyc) + ((((float)PIXB(bl))*(1.0f-fxc))+(((float)PIXB(br))*(fxc)))*(fyc)) ); } } else { //Stairstepping float fx, fy, fyc, fxc; double intp; pixel tr, tl, br, bl; int rrw = rw, rrh = rh; pixel * oq; oq = new pixel[sw*sh]; std::copy(src, src+(sw*sh), oq); rw = sw; rh = sh; while(rrw != rw && rrh != rh){ if(rw > rrw) rw *= 0.7; if(rh > rrh) rh *= 0.7; if(rw <= rrw) rw = rrw; if(rh <= rrh) rh = rrh; q = new pixel[rw*rh]; //Bilinear interpolation for (y=0; y<rh; y++) for (x=0; x<rw; x++) { fx = ((float)x)*((float)sw)/((float)rw); fy = ((float)y)*((float)sh)/((float)rh); fxc = modf(fx, &intp); fyc = modf(fy, &intp); fxceil = (int)ceil(fx); fyceil = (int)ceil(fy); if (fxceil>=sw) fxceil = sw-1; if (fyceil>=sh) fyceil = sh-1; tr = oq[sw*(int)floor(fy)+fxceil]; tl = oq[sw*(int)floor(fy)+(int)floor(fx)]; br = oq[sw*fyceil+fxceil]; bl = oq[sw*fyceil+(int)floor(fx)]; q[rw*y+x] = PIXRGB( (int)(((((float)PIXR(tl))*(1.0f-fxc))+(((float)PIXR(tr))*(fxc)))*(1.0f-fyc) + ((((float)PIXR(bl))*(1.0f-fxc))+(((float)PIXR(br))*(fxc)))*(fyc)), (int)(((((float)PIXG(tl))*(1.0f-fxc))+(((float)PIXG(tr))*(fxc)))*(1.0f-fyc) + ((((float)PIXG(bl))*(1.0f-fxc))+(((float)PIXG(br))*(fxc)))*(fyc)), (int)(((((float)PIXB(tl))*(1.0f-fxc))+(((float)PIXB(tr))*(fxc)))*(1.0f-fyc) + ((((float)PIXB(bl))*(1.0f-fxc))+(((float)PIXB(br))*(fxc)))*(fyc)) ); } delete[] oq; oq = q; sw = rw; sh = rh; } } return q; #endif }
pixel *Graphics::ptif_unpack(void *datain, int size, int *w, int *h){ int width, height, i, cx, cy, resCode; unsigned char *red_chan; unsigned char *green_chan; unsigned char *blue_chan; unsigned char *data = (unsigned char*)datain; unsigned char *undata; pixel *result; if(size<16){ printf("Image empty\n"); return NULL; } if(!(data[0]=='P' && data[1]=='T' && data[2]=='i')){ printf("Image header invalid\n"); return NULL; } width = data[4]|(data[5]<<8); height = data[6]|(data[7]<<8); i = (width*height)*3; undata = (unsigned char*)calloc(1, (width*height)*3); red_chan = (unsigned char*)calloc(1, width*height); green_chan = (unsigned char*)calloc(1, width*height); blue_chan = (unsigned char *)calloc(1, width*height); result = (pixel *)calloc(width*height, PIXELSIZE); resCode = BZ2_bzBuffToBuffDecompress((char *)undata, (unsigned *)&i, (char *)(data+8), size-8, 0, 0); if (resCode){ printf("Decompression failure, %d\n", resCode); free(red_chan); free(green_chan); free(blue_chan); free(undata); free(result); return NULL; } if(i != (width*height)*3){ printf("Result buffer size mismatch, %d != %d\n", i, (width*height)*3); free(red_chan); free(green_chan); free(blue_chan); free(undata); free(result); return NULL; } memcpy(red_chan, undata, width*height); memcpy(green_chan, undata+(width*height), width*height); memcpy(blue_chan, undata+((width*height)*2), width*height); for(cx = 0; cx<width; cx++){ for(cy = 0; cy<height; cy++){ result[width*(cy)+(cx)] = PIXRGB(red_chan[width*(cy)+(cx)], green_chan[width*(cy)+(cx)], blue_chan[width*(cy)+(cx)]); } } *w = width; *h = height; free(red_chan); free(green_chan); free(blue_chan); free(undata); return result; }
int graphics_LIFE(GRAPHICS_FUNC_ARGS) { pixel pc; if (cpart->ctype==NGT_LOTE)//colors for life states { if (cpart->tmp==2) pc = PIXRGB(255, 128, 0); else if (cpart->tmp==1) pc = PIXRGB(255, 255, 0); else pc = PIXRGB(255, 0, 0); } else if (cpart->ctype==NGT_FRG2)//colors for life states { if (cpart->tmp==2) pc = PIXRGB(0, 100, 50); else pc = PIXRGB(0, 255, 90); } else if (cpart->ctype==NGT_STAR)//colors for life states { if (cpart->tmp==4) pc = PIXRGB(0, 0, 128); else if (cpart->tmp==3) pc = PIXRGB(0, 0, 150); else if (cpart->tmp==2) pc = PIXRGB(0, 0, 190); else if (cpart->tmp==1) pc = PIXRGB(0, 0, 230); else pc = PIXRGB(0, 0, 70); } else if (cpart->ctype==NGT_FROG)//colors for life states { if (cpart->tmp==2) pc = PIXRGB(0, 100, 0); else pc = PIXRGB(0, 255, 0); } else if (cpart->ctype==NGT_BRAN)//colors for life states { if (cpart->tmp==1) pc = PIXRGB(150, 150, 0); else pc = PIXRGB(255, 255, 0); } else { pc = gmenu[cpart->ctype].colour; } *colr = PIXR(pc); *colg = PIXG(pc); *colb = PIXB(pc); return 0; }