void TCOD_image_rotate90(TCOD_image_t image, int numRotations) { int px,py; int width,height; numRotations = numRotations % 4; if (numRotations == 0 ) return; if ( numRotations < 0 ) numRotations += 4; TCOD_image_get_size(image,&width,&height); if (numRotations == 1) { /* rotate 90 degrees */ TCOD_image_t newImg=TCOD_image_new(height,width); image_data_t *img=(image_data_t *)image; image_data_t *img2=(image_data_t *)newImg; for (px = 0; px < width; px++ ) { for (py = 0; py < height; py++ ) { TCOD_color_t col1=TCOD_image_get_pixel(image,px,py); TCOD_image_put_pixel(newImg,height-1-py,px,col1); } } TCOD_image_delete_internal(image); /* update img with the new image content */ img->mipmaps = img2->mipmaps; img->sys_img=NULL; img->nb_mipmaps=img2->nb_mipmaps; free(img2); } else if ( numRotations == 2 ) { /* rotate 180 degrees */ int maxy=height/2 + ((height & 1) == 1? 1 : 0 ); for (px = 0; px < width; px++ ) { for (py = 0; py < maxy; py++ ) { if ( py != height-1-py || px < width/2 ) { TCOD_color_t col1=TCOD_image_get_pixel(image,px,py); TCOD_color_t col2=TCOD_image_get_pixel(image,width-1-px,height-1-py); TCOD_image_put_pixel(image,px,py,col2); TCOD_image_put_pixel(image,width-1-px,height-1-py,col1); } } } } else if (numRotations == 3) { /* rotate 270 degrees */ TCOD_image_t newImg=TCOD_image_new(height,width); image_data_t *img=(image_data_t *)image; image_data_t *img2=(image_data_t *)newImg; for (px = 0; px < width; px++ ) { for (py = 0; py < height; py++ ) { TCOD_color_t col1=TCOD_image_get_pixel(image,px,py); TCOD_image_put_pixel(newImg,py,width-1-px,col1); } } TCOD_image_delete_internal(image); /* update img with the new image content */ img->mipmaps = img2->mipmaps; img->sys_img=NULL; img->nb_mipmaps=img2->nb_mipmaps; free(img2); } }
TCODImage::TCODImage(int width, int height) : deleteData(true) { data=(void *)TCOD_image_new(width,height); }
void TCOD_image_scale(TCOD_image_t image, int neww, int newh) { image_data_t *img=(image_data_t *)image; int px,py; int width,height; image_data_t *newimg; TCOD_image_get_size(image,&width,&height); if ( neww==width && newh==height ) return; if ( neww == 0 || newh == 0 ) return; newimg=(image_data_t *)TCOD_image_new(neww,newh); if ( neww < width && newh < height ) { // scale down image, using supersampling for (py = 0; py < newh; py++ ) { float y0 = (float)(py) * height / newh; float y0floor = (float)floor(y0); float y0weight = 1.0f - (y0 - y0floor); int iy0 = (int)y0floor; float y1 = (float)(py+1) * height / newh; float y1floor = (float)floor(y1-0.00001); float y1weight = (y1 - y1floor); int iy1 = (int)y1floor; for (px = 0; px < neww; px++ ) { TCOD_color_t col; float x0 = (float)(px) * width / neww; float x0floor = (float)floor(x0); float x0weight = 1.0f - (x0 - x0floor); int ix0 = (int)x0floor; float x1 = (float)(px+1) * width / neww; float x1floor = (float)floor(x1- 0.00001); float x1weight = (x1 - x1floor); int ix1 = (int)x1floor; float r=0,g=0,b=0,sumweight=0.0f; int srcx,srcy; // left & right fractional edges for (srcy=(int)(y0+1); srcy < (int)y1; srcy++) { TCOD_color_t col_left=TCOD_image_get_pixel(image,ix0,srcy); TCOD_color_t col_right=TCOD_image_get_pixel(image,ix1,srcy); r += col_left.r * x0weight + col_right.r * x1weight; g += col_left.g * x0weight + col_right.g * x1weight; b += col_left.b * x0weight + col_right.b * x1weight; sumweight += x0weight+x1weight; } // top & bottom fractional edges for (srcx = (int)(x0+1); srcx < (int)x1; srcx++) { TCOD_color_t col_top=TCOD_image_get_pixel(image,srcx,iy0); TCOD_color_t col_bottom=TCOD_image_get_pixel(image,srcx,iy1); r += col_top.r * y0weight + col_bottom.r * y1weight; g += col_top.g * y0weight + col_bottom.g * y1weight; b += col_top.b * y0weight + col_bottom.b * y1weight; sumweight += y0weight+y1weight; } // center for (srcy=(int)(y0+1); srcy < (int)y1; srcy++) { for (srcx = (int)(x0+1); srcx < (int)x1; srcx++) { TCOD_color_t col=TCOD_image_get_pixel(image,srcx,srcy); r += col.r; g += col.g; b += col.b; sumweight += 1.0f; } } // corners col=TCOD_image_get_pixel(image,ix0,iy0); r += col.r * (x0weight * y0weight); g += col.g * (x0weight * y0weight); b += col.b * (x0weight * y0weight); sumweight += x0weight * y0weight; col=TCOD_image_get_pixel(image,ix0,iy1); r += col.r * (x0weight * y1weight); g += col.g * (x0weight * y1weight); b += col.b * (x0weight * y1weight); sumweight += x0weight * y1weight; col=TCOD_image_get_pixel(image,ix1,iy1); r += col.r * (x1weight * y1weight); g += col.g * (x1weight * y1weight); b += col.b * (x1weight * y1weight); sumweight += x1weight * y1weight; col=TCOD_image_get_pixel(image,ix1,iy0); r += col.r * (x1weight * y0weight); g += col.g * (x1weight * y0weight); b += col.b * (x1weight * y0weight); sumweight += x1weight * y0weight; sumweight = 1.0f / sumweight; r = r*sumweight + 0.5f; g = g*sumweight + 0.5f; b = b*sumweight + 0.5f; col.r=(int)r; col.g=(int)g; col.b=(int)b; TCOD_image_put_pixel(newimg,px,py,col); } } } else { // scale up image, using nearest neightbor for (py = 0; py < newh; py++ ) { int srcy = py * height / newh; for (px = 0; px < neww; px++ ) { int srcx = px * width / neww; TCOD_color_t col=TCOD_image_get_pixel(image,srcx,srcy); TCOD_image_put_pixel(newimg,px,py,col); } } } // destroy old image if ( img->mipmaps ) { int i; for ( i=0; i < img->nb_mipmaps; i++) { if ( img->mipmaps[i].buf ) free(img->mipmaps[i].buf); } free(img->mipmaps); } if ( img->sys_img ) { TCOD_sys_delete_bitmap(img->sys_img); } // update img with the new image content img->mipmaps = newimg->mipmaps; img->sys_img=NULL; img->nb_mipmaps=newimg->nb_mipmaps; free(newimg); }