image_p image_scale(image_p src, int w, int h,int mode) { image_p dst; uint8 * temp; uint8 recover = 0; uint32 spitch, dpitch; filter_base* filter = create_filter(mode); dst = image_create(w,h,src->dtype); dst->dontswizzle = 1; if(src->swizzle ==1){ unswizzle_swap(src); recover = 1; } temp = malloc(dst->w*src->h*src->bpb); memset(temp,0,dst->w*src->h*src->bpb); spitch = src->texw; dpitch = dst->texw; horiz_scale(filter,src->data,src->w,src->h,temp,dst->w,src->h,spitch,src->dtype); vert_scale (filter,temp,dst->w,src->h,dst->data,dst->w,dst->h,dpitch,src->dtype); free(temp); destroy_filter(filter); if(recover) swizzle_swap(src); return dst; }
/** * 建立 src 图像的亮度,饱和度版本 * * @param src 源图像 * @param saturation 饱合度 -100(灰度图像) 至 100(高彩色比图像) * @param brightness 亮度 -100(全黑) 至 100(全白) */ image_p create_saturation_brightness_image(image_p src, int saturation, int brightness) { uint32 y,x; uint8 recover = 0; image_p pimg; uint16 *p16,*psrc16; uint32 *p32,*psrc32; if(saturation<-100 || saturation>100) { nge_print("create_gray_image arg 'saturation' must between -100 to 100!"); return NULL; } if(brightness<-100 || brightness>100) { nge_print("create_gray_image arg 'brightness' must between -100 to 100!"); return NULL; } if(src->swizzle ==1){ unswizzle_swap(src); recover = 1; } pimg = image_create(src->w, src->h, src->dtype); for(y=0;y<src->h;y++) { if(src->dtype == DISPLAY_PIXEL_FORMAT_8888) { p32 = (uint32 *)pimg->data + y*src->texw; psrc32 = (uint32 *)src->data + y*src->texw; } else { p16 = (uint16 *)pimg->data + y*src->texw; psrc16 = (uint16 *)src->data + y*src->texw; } for(x=0;x<src->w;x++) { if(src->dtype == DISPLAY_PIXEL_FORMAT_8888) { *(p32 + x) = (uint32)get_saturation_brightness_color(pimg->dtype, *(psrc32 + x), saturation, brightness); } else { *(p16 + x) = (uint16)get_saturation_brightness_color(pimg->dtype, *(psrc16 + x), saturation, brightness); } } } if(recover) swizzle_swap(src); return pimg; }
/** * 建立 src 图像的灰度版本 * * @param src 源图像 * @param gray 灰度 0 到 100, 0 为源图像, 100 为纯灰色图像 */ image_p create_gray_image(image_p src, int gray) { uint32 y,x; uint8 recover = 0; image_p pimg; uint16 *p16,*psrc16; uint32 *p32,*psrc32; if(gray<0 || gray>100) { nge_print("create_gray_image arg 'gray' must between 0 to 100!"); return NULL; } if(src->swizzle ==1){ unswizzle_swap(src); recover = 1; } pimg = image_create(src->w, src->h, src->dtype); for(y=0;y<src->h;y++) { if(src->dtype == DISPLAY_PIXEL_FORMAT_8888) { p32 = (uint32 *)pimg->data + y*src->texw; psrc32 = (uint32 *)src->data + y*src->texw; } else { p16 = (uint16 *)pimg->data + y*src->texw; psrc16 = (uint16 *)src->data + y*src->texw; } for(x=0;x<src->w;x++) { if(src->dtype == DISPLAY_PIXEL_FORMAT_8888) { *(p32 + x) = (uint32)get_gray_color(pimg->dtype, *(psrc32 + x), gray); } else { *(p16 + x) = (uint16)get_gray_color(pimg->dtype, *(psrc16 + x), gray); } } } if(recover) swizzle_swap(src); return pimg; }
static void freetype2_drawtext(PFont pfont, image_p pimage, int x, int y, const void *text, int cc, int flags) { PFontFreetype pf = (PFontFreetype) pfont; uint16_t* value; FT_Glyph glyph; int pen_x = x; int pen_y = y + pf->size; int i; FT_BitmapGlyph bitmap_glyph; FT_Bitmap* bitmap; value = _nge_ft_conv_encoding(pfont, text, &cc); if (cc <= 0) return; if(pimage->swizzle ==1){ unswizzle_swap(pimage); pimage->dontswizzle = 1; } pimage->modified =1; for (i =0;i<cc;i++) { FT_Load_Glyph( pf->face, FT_Get_Char_Index( pf->face, value[i] ), FT_LOAD_DEFAULT ); if(pf->flags & FLAGS_FREETYPE_BOLD) FT_GlyphSlot_Embolden(pf->face->glyph); if(pf->flags & FLAGS_FREETYPE_ITALICS) FT_GlyphSlot_Oblique(pf->face->glyph); FT_Get_Glyph( pf->face->glyph, &glyph ); FT_Render_Glyph( pf->face->glyph, ft_render_mode_normal ); FT_Glyph_To_Bitmap( &glyph, ft_render_mode_normal, 0, 1 ); bitmap_glyph = (FT_BitmapGlyph)glyph; bitmap=&bitmap_glyph->bitmap; draw_one_word(pf,bitmap,pimage,pen_x + pf->face->glyph->bitmap_left,pen_y - pf->face->glyph->bitmap_top ); pen_x +=(pf->face->glyph->advance.x+pf->fix_width*72) >> 6 ; FT_Done_Glyph( glyph ); } }
image_p create_contrast_image(image_p src, int contrast){ uint32 y,x; uint8 recover = 0; image_p pimg; uint16 *p16,*psrc16; uint32 *p32,*psrc32; sint16 r,g,b,a; sint32 col; uint8 colmap[255]; if(contrast<-100 || contrast>100) { nge_print("create_contrast_image arg 'contrast' must between -100 to 100!"); return NULL; } contrast+=100; if(contrast == 100) return image_clone(src); if(src->swizzle ==1){ unswizzle_swap(src); recover = 1; } for(x=0;x<256;x++){ if(contrast < 100){ colmap[x] = max(0, min((int)(x - 128) * (contrast / 100) + 128, 255)); } else{ colmap[x] = max(0, min((int)(x - 128) * ((contrast - 100) * 1.28) + 128, 255)); } } pimg = image_create(src->w, src->h, src->dtype); for(y=0;y<src->h;y++) { for(x=0;x<src->w;x++){ if(src->dtype == DISPLAY_PIXEL_FORMAT_8888) { p32 = (uint32 *)pimg->data + y*src->texw; psrc32 = (uint32 *)src->data + y*src->texw; } else { p16 = (uint16 *)pimg->data + y*src->texw; psrc16 = (uint16 *)src->data + y*src->texw; } if(src->dtype == DISPLAY_PIXEL_FORMAT_4444){ col = *(psrc16 + x); GET_RGBA_4444(col, r,g,b,a); if(a > 0) { r = colmap[r]; g = colmap[g]; b = colmap[b]; } *(p16 + x) = MAKE_RGBA_4444(r,g,b,a); } } } if(recover) swizzle_swap(src); return pimg; }
image_p image_conv(image_p src, int dtype) { image_p dst; uint8 recover = 0; uint32 i,j; uint32 *src32, *dst32; uint16 *src16, *dst16; uint8 r,g,b,a; if(src->dtype == dtype) return image_clone(src); if(src->swizzle ==1){ unswizzle_swap(src); recover = 1; } dst = image_create(src->w, src->h, dtype); src32 = (uint32*)src->data; dst32 = (uint32*)dst->data; src16 = (uint16*)src->data; dst16 = (uint16*)dst->data; for(i = 0; i < src->h; i++) { for (j = 0; j<src->w; j++) { if(dtype == DISPLAY_PIXEL_FORMAT_8888){ if(src->dtype == DISPLAY_PIXEL_FORMAT_4444){ GET_RGBA_4444(src16[i*src->texw+j],r,g,b,a); dst32[i*dst->texw+j] = MAKE_RGBA_8888(r,g,b,a); } else if(src->dtype == DISPLAY_PIXEL_FORMAT_5551){ GET_RGBA_5551(src16[i*src->texw+j],r,g,b,a); dst32[i*dst->texw+j] = MAKE_RGBA_8888(r,g,b,a); } else if(src->dtype == DISPLAY_PIXEL_FORMAT_565){ GET_RGBA_565(src16[i*src->texw+j],r,g,b,a); dst32[i*dst->texw+j] = MAKE_RGBA_8888(r,g,b,a); } } else if(dtype == DISPLAY_PIXEL_FORMAT_4444){ if(src->dtype == DISPLAY_PIXEL_FORMAT_8888){ GET_RGBA_8888(src32[i*src->texw+j],r,g,b,a); dst16[i*dst->texw+j] = MAKE_RGBA_4444(r,g,b,a); } else if(src->dtype == DISPLAY_PIXEL_FORMAT_5551){ GET_RGBA_5551(src16[i*src->texw+j],r,g,b,a); dst16[i*dst->texw+j] = MAKE_RGBA_4444(r,g,b,a); } else if(src->dtype == DISPLAY_PIXEL_FORMAT_565){ GET_RGBA_565(src16[i*src->texw+j],r,g,b,a); dst16[i*dst->texw+j] = MAKE_RGBA_4444(r,g,b,a); } } else if(dtype == DISPLAY_PIXEL_FORMAT_5551){ if(src->dtype == DISPLAY_PIXEL_FORMAT_8888){ GET_RGBA_8888(src32[i*src->texw+j],r,g,b,a); dst16[i*dst->texw+j] = MAKE_RGBA_5551(r,g,b,a); } else if(src->dtype == DISPLAY_PIXEL_FORMAT_4444){ GET_RGBA_4444(src16[i*src->texw+j],r,g,b,a); dst16[i*dst->texw+j] = MAKE_RGBA_5551(r,g,b,a); } else if(src->dtype == DISPLAY_PIXEL_FORMAT_565){ GET_RGBA_565(src16[i*src->texw+j],r,g,b,a); dst16[i*dst->texw+j] = MAKE_RGBA_5551(r,g,b,a); } } else if(dtype == DISPLAY_PIXEL_FORMAT_565){ if(src->dtype == DISPLAY_PIXEL_FORMAT_8888){ GET_RGBA_8888(src32[i*src->texh+j],r,g,b,a); dst16[i*dst->texh+j] = MAKE_RGBA_565(r,g,b,a); } else if(src->dtype == DISPLAY_PIXEL_FORMAT_4444){ GET_RGBA_4444(src16[i*src->texh+j],r,g,b,a); dst16[i*dst->texh+j] = MAKE_RGBA_565(r,g,b,a); } else if(src->dtype == DISPLAY_PIXEL_FORMAT_5551){ GET_RGBA_5551(src16[i*src->texh+j],r,g,b,a); dst16[i*dst->texh+j] = MAKE_RGBA_565(r,g,b,a); } } } } swizzle_swap(dst); if(recover) swizzle_swap(src); return dst; }
image_p image_rot(image_p src,float angel) { image_p dst; uint8 recover = 0; double sx,rs0,rs1,sy; double rangel; pointf d0,d1,d2,d3,d4; float x1,x2,y1,y2; sint16 xo, yo, wo, ho; uint32 i,j; uint32 *src32, *dst32; uint16 *src16, *dst16; uint16 r,g,b,a; uint16 r2,g2,b2,a2; uint8 smc; float xbx; while(angel > 360.0f) angel-=360.0f; while(angel<0) angel+=360.0f; if(angel == 0) return image_clone(src); if(src->swizzle ==1){ unswizzle_swap(src); recover = 1; } rangel = angel*3.1415926f/180.0f; sx = cos(rangel); rs0 = sin(rangel); rs1 = -sin(rangel); sy = cos(rangel); d0.x = 0; d0.y = 0; d1 = image_rot_pointf(d0, sx, sy, rs0, rs1); d0.x = src->w; d2 = image_rot_pointf(d0, sx, sy, rs0, rs1); d0.y = src->h; d3 = image_rot_pointf(d0, sx, sy, rs0, rs1); d0.x = 0; d4 = image_rot_pointf(d0, sx, sy, rs0, rs1); x1 = min(d1.x, min(d2.x, min(d3.x, d4.x))); x2 = max(d1.x, max(d2.x, max(d3.x, d4.x))); y1 = min(d1.y, min(d2.y, min(d3.y, d4.y))); y2 = max(d1.y, max(d2.y, max(d3.y, d4.y))); xo = x1; yo = y1; wo = x2 - xo; ho = y2 - yo; dst = image_create(wo, ho, src->dtype); src32 = (uint32*)src->data; dst32 = (uint32*)dst->data; src16 = (uint16*)src->data; dst16 = (uint16*)dst->data; for(i = 0; i < dst->h; i++) { for (j = 0; j<dst->w; j++) { d0.x = j; d0.y = i; d0 = image_rot_pointf(d0, sx, sy, rs0, rs1); // easy way smc = 1; r2 = 0; g2 = 0; b2 = 0; a2 = 0; if(src->dtype == DISPLAY_PIXEL_FORMAT_8888){ if((int)d0.y-yo < src->texh && (int)d0.x-xo < src->texw){ //dst16[i*dst->texw+j] = src16[((int)d0.y-yo)*src->texw+(int)d0.x-xo]; GET_RGBA_8888(src32[((int)d0.y-yo)*src->texw+(int)d0.x-xo], r, g, b, a); xbx = 1.0f - ((d0.y-yo) - (int)(d0.y-yo)); r2 = r * xbx; g2 = g * xbx; b2 = b * xbx; a2 = a * xbx; if((int)d0.y-yo+1 < src->texh){ smc++; xbx = 1.0f - xbx; GET_RGBA_8888(src32[((int)d0.y-yo+1)*src->texw+(int)d0.x-xo], r, g, b, a); r2 += r * xbx; g2 += g * xbx; b2 += b * xbx; a2 += a * xbx; } r = min(r2, 255); g = min(g2, 255); b = min(b2, 255); a = min(a2, 255); dst32[i*dst->texw+j] = MAKE_RGBA_8888(r,g,b,a); } } else if(src->dtype == DISPLAY_PIXEL_FORMAT_4444){ if((int)d0.y-yo < src->texh && (int)d0.x-xo < src->texw){ //dst16[i*dst->texw+j] = src16[((int)d0.y-yo)*src->texw+(int)d0.x-xo]; GET_RGBA_4444(src16[((int)d0.y-yo)*src->texw+(int)d0.x-xo], r, g, b, a); xbx = 1.0f - ((d0.y-yo) - (int)(d0.y-yo)); r2 = r * xbx; g2 = g * xbx; b2 = b * xbx; a2 = a * xbx; if((int)d0.y-yo+1 < src->texh){ smc++; xbx = 1.0f - xbx; GET_RGBA_4444(src16[((int)d0.y-yo+1)*src->texw+(int)d0.x-xo], r, g, b, a); r2 += r * xbx; g2 += g * xbx; b2 += b * xbx; a2 += a * xbx; } r = min(r2, 255); g = min(g2, 255); b = min(b2, 255); a = min(a2, 255); dst16[i*dst->texw+j] = MAKE_RGBA_4444(r,g,b,a); } } else if(src->dtype == DISPLAY_PIXEL_FORMAT_5551){ if((int)d0.y-yo < src->texh && (int)d0.x-xo < src->texw){ //dst16[i*dst->texw+j] = src16[((int)d0.y-yo)*src->texw+(int)d0.x-xo]; GET_RGBA_5551(src16[((int)d0.y-yo)*src->texw+(int)d0.x-xo], r, g, b, a); xbx = 1.0f - ((d0.y-yo) - (int)(d0.y-yo)); r2 = r * xbx; g2 = g * xbx; b2 = b * xbx; a2 = a * xbx; if((int)d0.y-yo+1 < src->texh){ smc++; xbx = 1.0f - xbx; GET_RGBA_5551(src16[((int)d0.y-yo+1)*src->texw+(int)d0.x-xo], r, g, b, a); r2 += r * xbx; g2 += g * xbx; b2 += b * xbx; a2 += a * xbx; } r = min(r2, 255); g = min(g2, 255); b = min(b2, 255); a = min(a2, 255); dst16[i*dst->texw+j] = MAKE_RGBA_5551(r,g,b,a); } } else{ if((int)d0.y-yo < src->texh && (int)d0.x-xo < src->texw){ //dst16[i*dst->texw+j] = src16[((int)d0.y-yo)*src->texw+(int)d0.x-xo]; GET_RGBA_565(src16[((int)d0.y-yo)*src->texw+(int)d0.x-xo], r, g, b, a); xbx = 1.0f - ((d0.y-yo) - (int)(d0.y-yo)); r2 = r * xbx; g2 = g * xbx; b2 = b * xbx; a2 = a * xbx; if((int)d0.y-yo+1 < src->texh){ smc++; xbx = 1.0f - xbx; GET_RGBA_565(src16[((int)d0.y-yo+1)*src->texw+(int)d0.x-xo], r, g, b, a); r2 += r * xbx; g2 += g * xbx; b2 += b * xbx; a2 += a * xbx; } r = min(r2, 255); g = min(g2, 255); b = min(b2, 255); a = min(a2, 255); dst16[i*dst->texw+j] = MAKE_RGBA_565(r,g,b,a); } } } } swizzle_swap(dst); if(recover) swizzle_swap(src); return dst; }