void CVHW::count_run ( cv::Mat t_image) { //cv::Mat t_image =origin_image.clone(); int m = t_image.rows; int n = t_image.cols; runs = 0; bool flag; for ( int i = 0 ; i<m ; i++ ) { flag = false; for ( int j=0 ; j<n ; j++) { //printf("%d",get_pix(i,j)>0?1:0); if ( get_pix(t_image,i,j) > 0 && flag ==false) //meet the first 1 of a new run, mark flag as true { flag = true; runs++; } else if ( get_pix(t_image,i,j) == 0 && flag==true ) { flag = false; //end of a run, mark flag as false; } } //printf("\n"); } }
void CVHW::initialize_run_table(cv::Mat t_image ) { //cv::Mat* t_image = new cv::Mat(origin_image); int m = t_image.rows; int n = t_image.cols; row_start = new int[m]; row_end = new int[m]; row = new int[runs+1]; start_col = new int[runs+1]; end_col = new int[runs+1]; perm_label = new int[runs+1]; label = new int[runs+1]; next = new int[runs+1]; eq_class = new int[runs+1]; bool flag; int num_runs = 0; for ( int i = 0 ; i<m ; i++ ) { flag = false; row_start[i] = row_end[i] = 0; for ( int j=0 ; j<n ; j++) { if ( get_pix(t_image,i,j) > 0 && flag ==false) //meet the first 1 of a new run, mark flag as true { flag = true; num_runs++; //update run table if ( row_start[i]==0 ) row_start[i] = num_runs; //update row_start[i]; row_end[i] = num_runs; //update row_end[i]; row[num_runs] = i; //initialize row start_col[num_runs] = j; //initialize start_col perm_label[num_runs] = 0; //initialize perm_label label[num_runs] = 0; //initialize label next[num_runs] = 0; //initialize next eq_class[num_runs] = 0; //initialize eq_class } else if ( get_pix(t_image,i,j) == 0 && flag==true ) { flag = false; //end of a run, mark flag as false; end_col[num_runs]=j-1; //initialize end_col } } if ( flag ) { end_col[num_runs]=n-1; } } }
//a binary image (threshold at 128) void CVHW::binary(cv::Mat& t_image, int threshold) { int m = t_image.rows; int n = t_image.cols; //int a,b; //a=b=0; printf("binary\n"); printf("Threshold is %d\n",threshold); for ( int i = 0 ; i<m ; i++ ) { for ( int j = 0 ; j<n ; j++ ) { //printf("%d ",get_pix(i,j)); if ( get_pix(t_image,i,j)>=threshold ) { //a++; set_pix(t_image,i,j,255); } else { //b++; set_pix(t_image,i,j,0); } } } //printf("%d,%d\n",a,b); }
//a histogram, return an array pointer int* CVHW::histogram(cv::Mat& t_image) { int* histogram_array=new int[256]; int m = t_image.rows; int n = t_image.cols; printf("histogram\n"); for ( int i = 0 ; i<256 ; i++ ) { histogram_array[i]=0; } for ( int i=0 ; i<m ; i++ ) { for ( int j=0 ; j<n ; j++ ) { histogram_array[get_pix(t_image,i,j)]++; } } return histogram_array; }
int set_square(t_data *data, t_bunny_ini_scope *scope) { const char *tmp; if ((data->obj.square = bunny_realloc(data->obj.square, (data->obj.nb_sq + 1) * sizeof(t_square))) == NULL) return (errstr("realloc square failed\n")); data->obj.square[data->obj.nb_sq].pix = NULL; if ((tmp = bunny_ini_scope_get_field(scope, "size", 0)) == NULL) return (errstr("square size failed\n")); data->obj.square[data->obj.nb_sq].size = (int)get_unsnbr(tmp); if ((tmp = bunny_ini_scope_get_field(scope, "obj", 0)) == NULL) return (errstr("square obj failed\n")); data->obj.square[data->obj.nb_sq].obj = (char)get_unsnbr(tmp); if (get_centre(&data->obj.square[data->obj.nb_sq].c, scope, "pos") != 0) return (errstr("square pos failed\n")); if ((tmp = bunny_ini_scope_get_field(scope, "pix", 0)) != NULL) get_pix(&data->obj.square[data->obj.nb_sq], tmp); data->obj.square[data->obj.nb_sq].color.full = BLACK; data->obj.nb_sq += 1; return (0); }
void image_upsize(image_s * pdest, image_s * psrc, int32_t width, int32_t height) { int32_t vx, vy; #if !defined __i386__ && !defined __x86_64__ int32_t rx, ry; pix vcol; if((pdest == NULL) || (psrc == NULL)) return; for(vy = 0; vy < height; vy++) { for(vx = 0; vx < width; vx++) { rx = ((vx * psrc->width) / width); ry = ((vy * psrc->height) / height); vcol = get_pix(psrc, rx, ry); #else pix vcol,vcol1,vcol2,vcol3,vcol4; float rx,ry; float width_scale, height_scale; float x_dist, y_dist; width_scale = (float)psrc->width / (float)width; height_scale = (float)psrc->height / (float)height; for(vy = 0;vy < height; vy++) { for(vx = 0;vx < width; vx++) { rx = vx * width_scale; ry = vy * height_scale; vcol1 = get_pix(psrc, (int32_t)rx, (int32_t)ry); vcol2 = get_pix(psrc, ((int32_t)rx)+1, (int32_t)ry); vcol3 = get_pix(psrc, (int32_t)rx, ((int32_t)ry)+1); vcol4 = get_pix(psrc, ((int32_t)rx)+1, ((int32_t)ry)+1); x_dist = rx - ((float)((int32_t)rx)); y_dist = ry - ((float)((int32_t)ry)); vcol = COL_FULL( (uint8_t)((COL_RED(vcol1)*(1.0-x_dist) + COL_RED(vcol2)*(x_dist))*(1.0-y_dist) + (COL_RED(vcol3)*(1.0-x_dist) + COL_RED(vcol4)*(x_dist))*(y_dist)), (uint8_t)((COL_GREEN(vcol1)*(1.0-x_dist) + COL_GREEN(vcol2)*(x_dist))*(1.0-y_dist) + (COL_GREEN(vcol3)*(1.0-x_dist) + COL_GREEN(vcol4)*(x_dist))*(y_dist)), (uint8_t)((COL_BLUE(vcol1)*(1.0-x_dist) + COL_BLUE(vcol2)*(x_dist))*(1.0-y_dist) + (COL_BLUE(vcol3)*(1.0-x_dist) + COL_BLUE(vcol4)*(x_dist))*(y_dist)), (uint8_t)((COL_ALPHA(vcol1)*(1.0-x_dist) + COL_ALPHA(vcol2)*(x_dist))*(1.0-y_dist) + (COL_ALPHA(vcol3)*(1.0-x_dist) + COL_ALPHA(vcol4)*(x_dist))*(y_dist)) ); #endif put_pix_alpha_replace(pdest, vx, vy, vcol); } } } void image_downsize(image_s * pdest, image_s * psrc, int32_t width, int32_t height) { int32_t vx, vy; pix vcol; int32_t i, j; #if !defined __i386__ && !defined __x86_64__ int32_t rx, ry, rx_next, ry_next; int red, green, blue, alpha; int factor; if((pdest == NULL) || (psrc == NULL)) return; for(vy = 0; vy < height; vy++) { for(vx = 0; vx < width; vx++) { rx = ((vx * psrc->width) / width); ry = ((vy * psrc->height) / height); red = green = blue = alpha = 0; rx_next = rx + (psrc->width / width); ry_next = ry + (psrc->width / width); factor = 0; for( j = rx; j < rx_next; j++) { for( i = ry; i < ry_next; i++) { factor += 1; vcol = get_pix(psrc, j, i); red += COL_RED(vcol); green += COL_GREEN(vcol); blue += COL_BLUE(vcol); alpha += COL_ALPHA(vcol); } } red /= factor; green /= factor; blue /= factor; alpha /= factor; /* on sature les valeurs */ red = (red > 255) ? 255 : ((red < 0) ? 0 : red ); green = (green > 255) ? 255 : ((green < 0) ? 0 : green); blue = (blue > 255) ? 255 : ((blue < 0) ? 0 : blue ); alpha = (alpha > 255) ? 255 : ((alpha < 0) ? 0 : alpha); #else float rx,ry; float width_scale, height_scale; float red, green, blue, alpha; int32_t half_square_width, half_square_height; float round_width, round_height; if( (pdest == NULL) || (psrc == NULL) ) return; width_scale = (float)psrc->width / (float)width; height_scale = (float)psrc->height / (float)height; half_square_width = (int32_t)(width_scale / 2.0); half_square_height = (int32_t)(height_scale / 2.0); round_width = (width_scale / 2.0) - (float)half_square_width; round_height = (height_scale / 2.0) - (float)half_square_height; if(round_width > 0.0) half_square_width++; else round_width = 1.0; if(round_height > 0.0) half_square_height++; else round_height = 1.0; for(vy = 0;vy < height; vy++) { for(vx = 0;vx < width; vx++) { rx = vx * width_scale; ry = vy * height_scale; vcol = get_pix(psrc, (int32_t)rx, (int32_t)ry); red = green = blue = alpha = 0.0; for(j=0;j<half_square_height<<1;j++) { for(i=0;i<half_square_width<<1;i++) { vcol = get_pix(psrc, ((int32_t)rx)-half_square_width+i, ((int32_t)ry)-half_square_height+j); if(((j == 0) || (j == (half_square_height<<1)-1)) && ((i == 0) || (i == (half_square_width<<1)-1))) { red += round_width*round_height*(float)COL_RED (vcol); green += round_width*round_height*(float)COL_GREEN(vcol); blue += round_width*round_height*(float)COL_BLUE (vcol); alpha += round_width*round_height*(float)COL_ALPHA(vcol); } else if((j == 0) || (j == (half_square_height<<1)-1)) { red += round_height*(float)COL_RED (vcol); green += round_height*(float)COL_GREEN(vcol); blue += round_height*(float)COL_BLUE (vcol); alpha += round_height*(float)COL_ALPHA(vcol); } else if((i == 0) || (i == (half_square_width<<1)-1)) { red += round_width*(float)COL_RED (vcol); green += round_width*(float)COL_GREEN(vcol); blue += round_width*(float)COL_BLUE (vcol); alpha += round_width*(float)COL_ALPHA(vcol); } else { red += (float)COL_RED (vcol); green += (float)COL_GREEN(vcol); blue += (float)COL_BLUE (vcol); alpha += (float)COL_ALPHA(vcol); } } } red /= width_scale*height_scale; green /= width_scale*height_scale; blue /= width_scale*height_scale; alpha /= width_scale*height_scale; /* on sature les valeurs */ red = (red > 255.0)? 255.0 : ((red < 0.0)? 0.0:red ); green = (green > 255.0)? 255.0 : ((green < 0.0)? 0.0:green); blue = (blue > 255.0)? 255.0 : ((blue < 0.0)? 0.0:blue ); alpha = (alpha > 255.0)? 255.0 : ((alpha < 0.0)? 0.0:alpha); #endif put_pix_alpha_replace(pdest, vx, vy, COL_FULL((uint8_t)red, (uint8_t)green, (uint8_t)blue, (uint8_t)alpha)); } } } image_s * image_resize(image_s * src_image, int32_t width, int32_t height) { image_s * dst_image; dst_image = image_new(width, height); if( !dst_image ) return NULL; if( (src_image->width < width) || (src_image->height < height) ) image_upsize(dst_image, src_image, width, height); else image_downsize(dst_image, src_image, width, height); return dst_image; } unsigned char * image_save_to_jpeg_buf(image_s * pimage, int * size) { struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; JSAMPROW row_pointer[1]; int row_stride; char *data; int i, x; struct my_dst_mgr dst; cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); jpeg_memory_dest(&cinfo, &dst); cinfo.image_width = pimage->width; cinfo.image_height = pimage->height; cinfo.input_components = 3; cinfo.in_color_space = JCS_RGB; jpeg_set_defaults(&cinfo); jpeg_set_quality(&cinfo, JPEG_QUALITY, TRUE); jpeg_start_compress(&cinfo, TRUE); row_stride = cinfo.image_width * 3; if((data = malloc(row_stride)) == NULL) { DPRINTF(E_WARN, L_METADATA, "malloc failed\n"); if (dst.buf) free(dst.buf); jpeg_destroy_compress(&cinfo); return NULL; } i = 0; while(cinfo.next_scanline < cinfo.image_height) { for(x = 0; x < pimage->width; x++) { data[x * 3] = COL_RED(pimage->buf[i]); data[x * 3 + 1] = COL_GREEN(pimage->buf[i]); data[x * 3 + 2] = COL_BLUE(pimage->buf[i]); i++; } row_pointer[0] = (unsigned char *)data; jpeg_write_scanlines(&cinfo, row_pointer, 1); } jpeg_finish_compress(&cinfo); *size = dst.used; free(data); jpeg_destroy_compress(&cinfo); return dst.buf; } char * image_save_to_jpeg_file(image_s * pimage, char * path) { int nwritten, size = 0; unsigned char * buf; FILE * dst_file; buf = image_save_to_jpeg_buf(pimage, &size); if( !buf ) return NULL; dst_file = fopen(path, "w"); if( !dst_file ) { free(buf); return NULL; } nwritten = fwrite(buf, 1, size, dst_file); fclose(dst_file); free(buf); return (nwritten == size) ? path : NULL; }
void image_downsize_gd(image *im) { int x, y; float sy1, sy2, sx1, sx2; int dstX = 0, dstY = 0, srcX = 0, srcY = 0; float width_scale, height_scale; int dstW = im->target_width; int dstH = im->target_height; int srcW = im->width; int srcH = im->height; if (im->height_padding) { dstY = im->height_padding; dstH = im->height_inner; } if (im->width_padding) { dstX = im->width_padding; dstW = im->width_inner; } width_scale = (float)srcW / dstW; height_scale = (float)srcH / dstH; for (y = dstY; (y < dstY + dstH); y++) { sy1 = (float)(y - dstY) * height_scale; sy2 = (float)((y + 1) - dstY) * height_scale; for (x = dstX; (x < dstX + dstW); x++) { float sx, sy; float spixels = 0; float red = 0.0, green = 0.0, blue = 0.0, alpha = 0.0; if (!im->has_alpha) alpha = 255.0; sx1 = (float)(x - dstX) * width_scale; sx2 = (float)((x + 1) - dstX) * width_scale; sy = sy1; //DEBUG_TRACE("sx1 %.2f, sx2 %.2f, sy1 %.2f, sy2 %.2f\n", sx1, sx2, sy1, sy2); do { float yportion; //DEBUG_TRACE(" yportion(sy %.2f, sy1 %.2f, sy2 %.2f) = ", sy, sy1, sy2); if (floor2(sy) == floor2(sy1)) { yportion = 1.0 - (sy - floor2(sy)); if (yportion > sy2 - sy1) { yportion = sy2 - sy1; } sy = floor2(sy); } else if (sy == floor2(sy2)) { yportion = sy2 - floor2(sy2); } else { yportion = 1.0; } //DEBUG_TRACE("%.2f\n", yportion); sx = sx1; do { float xportion = 1.0; float pcontribution; pix p; //DEBUG_TRACE(" xportion(sx %.2f, sx1 %.2f, sx2 %.2f) = ", sx, sx1, sx2); if (floor2(sx) == floor2(sx1)) { xportion = 1.0 - (sx - floor2(sx)); if (xportion > sx2 - sx1) { xportion = sx2 - sx1; } sx = floor2(sx); } else if (sx == floor2(sx2)) { xportion = sx2 - floor2(sx2); } else { xportion = 1.0; } //DEBUG_TRACE("%.2f\n", xportion); pcontribution = xportion * yportion; p = get_pix(im, (int32_t)sx + srcX, (int32_t)sy + srcY); /* DEBUG_TRACE(" merging with pix %d, %d: src %x (%d %d %d %d), pcontribution %.2f\n", (int32_t)sx + srcX, (int32_t)sy + srcY, p, COL_RED(p), COL_GREEN(p), COL_BLUE(p), COL_ALPHA(p), pcontribution); */ red += COL_RED(p) * pcontribution; green += COL_GREEN(p) * pcontribution; blue += COL_BLUE(p) * pcontribution; if (im->has_alpha) alpha += COL_ALPHA(p) * pcontribution; spixels += pcontribution; sx += 1.0; } while (sx < sx2); sy += 1.0; } while (sy < sy2); if (spixels != 0.0) { //DEBUG_TRACE(" rgba (%.2f %.2f %.2f %.2f) spixels %.2f\n", red, green, blue, alpha, spixels); spixels = 1 / spixels; red *= spixels; green *= spixels; blue *= spixels; if (im->has_alpha) alpha *= spixels; } /* Clamping to allow for rounding errors above */ if (red > 255.0) red = 255.0; if (green > 255.0) green = 255.0; if (blue > 255.0) blue = 255.0; if (im->has_alpha && alpha > 255.0) alpha = 255.0; /* DEBUG_TRACE(" -> %d, %d %x (%d %d %d %d)\n", x, y, COL_FULL((int)red, (int)green, (int)blue, (int)alpha), (int)red, (int)green, (int)blue, (int)alpha); */ if (im->orientation != ORIENTATION_NORMAL) { int ox, oy; // new destination pixel coordinates after rotating image_get_rotated_coords(im, x, y, &ox, &oy); if (im->orientation >= 5) { // 90 and 270 rotations, width/height are swapped so we have to use alternate put_pix method put_pix_rotated( im, ox, oy, im->target_height, COL_FULL(ROUND_FLOAT_TO_INT(red), ROUND_FLOAT_TO_INT(green), ROUND_FLOAT_TO_INT(blue), ROUND_FLOAT_TO_INT(alpha)) ); } else { put_pix( im, ox, oy, COL_FULL(ROUND_FLOAT_TO_INT(red), ROUND_FLOAT_TO_INT(green), ROUND_FLOAT_TO_INT(blue), ROUND_FLOAT_TO_INT(alpha)) ); } } else { put_pix( im, x, y, COL_FULL(ROUND_FLOAT_TO_INT(red), ROUND_FLOAT_TO_INT(green), ROUND_FLOAT_TO_INT(blue), ROUND_FLOAT_TO_INT(alpha)) ); } } } }
void image_downsize_gd_fixed_point(image *im) { int x, y; fixed_t sy1, sy2, sx1, sx2; int dstX = 0, dstY = 0, srcX = 0, srcY = 0; fixed_t width_scale, height_scale; int dstW = im->target_width; int dstH = im->target_height; int srcW = im->width; int srcH = im->height; if (im->height_padding) { dstY = im->height_padding; dstH = im->height_inner; } if (im->width_padding) { dstX = im->width_padding; dstW = im->width_inner; } width_scale = fixed_div(int_to_fixed(srcW), int_to_fixed(dstW)); height_scale = fixed_div(int_to_fixed(srcH), int_to_fixed(dstH)); for (y = dstY; (y < dstY + dstH); y++) { sy1 = fixed_mul(int_to_fixed(y - dstY), height_scale); sy2 = fixed_mul(int_to_fixed((y + 1) - dstY), height_scale); for (x = dstX; (x < dstX + dstW); x++) { fixed_t sx, sy; fixed_t spixels = 0; fixed_t red = 0, green = 0, blue = 0, alpha = 0; if (!im->has_alpha) alpha = FIXED_255; sx1 = fixed_mul(int_to_fixed(x - dstX), width_scale); sx2 = fixed_mul(int_to_fixed((x + 1) - dstX), width_scale); sy = sy1; /* DEBUG_TRACE("sx1 %f, sx2 %f, sy1 %f, sy2 %f\n", fixed_to_float(sx1), fixed_to_float(sx2), fixed_to_float(sy1), fixed_to_float(sy2)); */ do { fixed_t yportion; //DEBUG_TRACE(" yportion(sy %f, sy1 %f, sy2 %f) = ", fixed_to_float(sy), fixed_to_float(sy1), fixed_to_float(sy2)); if (fixed_floor(sy) == fixed_floor(sy1)) { yportion = FIXED_1 - (sy - fixed_floor(sy)); if (yportion > sy2 - sy1) { yportion = sy2 - sy1; } sy = fixed_floor(sy); } else if (sy == fixed_floor(sy2)) { yportion = sy2 - fixed_floor(sy2); } else { yportion = FIXED_1; } //DEBUG_TRACE("%f\n", fixed_to_float(yportion)); sx = sx1; do { fixed_t xportion; fixed_t pcontribution; pix p; //DEBUG_TRACE(" xportion(sx %f, sx1 %f, sx2 %f) = ", fixed_to_float(sx), fixed_to_float(sx1), fixed_to_float(sx2)); if (fixed_floor(sx) == fixed_floor(sx1)) { xportion = FIXED_1 - (sx - fixed_floor(sx)); if (xportion > sx2 - sx1) { xportion = sx2 - sx1; } sx = fixed_floor(sx); } else if (sx == fixed_floor(sx2)) { xportion = sx2 - fixed_floor(sx2); } else { xportion = FIXED_1; } //DEBUG_TRACE("%f\n", fixed_to_float(xportion)); pcontribution = fixed_mul(xportion, yportion); p = get_pix(im, fixed_to_int(sx + srcX), fixed_to_int(sy + srcY)); /* DEBUG_TRACE(" merging with pix %d, %d: src %x (%d %d %d %d), pcontribution %f\n", fixed_to_int(sx + srcX), fixed_to_int(sy + srcY), p, COL_RED(p), COL_GREEN(p), COL_BLUE(p), COL_ALPHA(p), fixed_to_float(pcontribution)); */ red += fixed_mul(int_to_fixed(COL_RED(p)), pcontribution); green += fixed_mul(int_to_fixed(COL_GREEN(p)), pcontribution); blue += fixed_mul(int_to_fixed(COL_BLUE(p)), pcontribution); if (im->has_alpha) alpha += fixed_mul(int_to_fixed(COL_ALPHA(p)), pcontribution); spixels += pcontribution; sx += FIXED_1; } while (sx < sx2); sy += FIXED_1; } while (sy < sy2); // If rgba get too large for the fixed-point representation, fallback to the floating point routine // This should only happen with very large images if (red < 0 || green < 0 || blue < 0 || alpha < 0) { warn("fixed-point overflow: %d %d %d %d\n", red, green, blue, alpha); return image_downsize_gd(im); } if (spixels != 0) { /* DEBUG_TRACE(" rgba (%f %f %f %f) spixels %f\n", fixed_to_float(red), fixed_to_float(green), fixed_to_float(blue), fixed_to_float(alpha), fixed_to_float(spixels)); */ spixels = fixed_div(FIXED_1, spixels); red = fixed_mul(red, spixels); green = fixed_mul(green, spixels); blue = fixed_mul(blue, spixels); if (im->has_alpha) alpha = fixed_mul(alpha, spixels); } /* Clamping to allow for rounding errors above */ if (red > FIXED_255) red = FIXED_255; if (green > FIXED_255) green = FIXED_255; if (blue > FIXED_255) blue = FIXED_255; if (im->has_alpha && alpha > FIXED_255) alpha = FIXED_255; /* DEBUG_TRACE(" -> %d, %d %x (%d %d %d %d)\n", x, y, COL_FULL(fixed_to_int(red), fixed_to_int(green), fixed_to_int(blue), fixed_to_int(alpha)), fixed_to_int(red), fixed_to_int(green), fixed_to_int(blue), fixed_to_int(alpha)); */ if (im->orientation != ORIENTATION_NORMAL) { int ox, oy; // new destination pixel coordinates after rotating image_get_rotated_coords(im, x, y, &ox, &oy); if (im->orientation >= 5) { // 90 and 270 rotations, width/height are swapped so we have to use alternate put_pix method put_pix_rotated( im, ox, oy, im->target_height, COL_FULL(fixed_to_int(red), fixed_to_int(green), fixed_to_int(blue), fixed_to_int(alpha)) ); } else { put_pix( im, ox, oy, COL_FULL(fixed_to_int(red), fixed_to_int(green), fixed_to_int(blue), fixed_to_int(alpha)) ); } } else { put_pix( im, x, y, COL_FULL(fixed_to_int(red), fixed_to_int(green), fixed_to_int(blue), fixed_to_int(alpha)) ); } } } }
int main(int argn, char ** argv) { if(argn < 4) { usage("Wrong argument count", *argv); } // read width and height const int w = atoi(argv[1]); const int h = atoi(argv[2]); if(w < 1 || h < 1) { usage("Both width and height must be positive integers", *argv); } const int pix_count = w * h; // read sigma and prepare normalized kernel (sum = 1) const float sigma = atof(argv[3]); float kernel[MAX_KERNEL_RADIUS + 1]; float kernel_sum = 0.0f; for(int k = 0; k <= MAX_KERNEL_RADIUS; k++) { kernel_sum += kernel[k] = gaussian(sigma, k); } kernel_sum = 2.0 * kernel_sum - kernel[0]; for(int k = 0; k <= MAX_KERNEL_RADIUS; k++) { kernel[k] /= kernel_sum; } // dump the kernel printf("Convolution kernel:"); for(int k = -MAX_KERNEL_RADIUS; k <= MAX_KERNEL_RADIUS; k++) { printf(" %f", kernel[k < 0 ? -k : k]); } printf("\n"); // prepare buffers uint8_t * const data_ptr = (uint8_t*)malloc(pix_count); uint8_t * const temp_ptr = (uint8_t*)malloc(pix_count); // measure time of processing of all images const double begin = timer_ms(); for(int i = 4; i < argn; i++) { // read input data printf("Processing '%s'\n", argv[i]); FILE * const src_file = fopen(argv[i], "rb"); if(NULL == src_file || 1 != fread(data_ptr, pix_count, 1, src_file)) { error(argv[i]); } fclose(src_file); // vertical pass: for each pixel uint8_t * out_pix_ptr = temp_ptr; for(int y = 0; y < h; y++) { for(int x = 0; x < w; x++) { // sum up all weighted neighbors and the pixel itself float result = kernel[0] * get_pix(data_ptr, w, h, x, y); for(int k = 1; k <= MAX_KERNEL_RADIUS; k++) { result += kernel[k] * (get_pix(data_ptr, w, h, x, y + k) + get_pix(data_ptr, w, h, x, y - k)); } *(out_pix_ptr++) = saturate((int)result, 256); } } // horizontal pass: for each pixel out_pix_ptr = data_ptr; for(int y = 0; y < h; y++) { for(int x = 0; x < w; x++) { // sum up all weighted neighbors and the pixel itself float result = kernel[0] * get_pix(temp_ptr, w, h, x, y); for(int k = 1; k <= MAX_KERNEL_RADIUS; k++) { result += kernel[k] * (get_pix(temp_ptr, w, h, x + k, y) + get_pix(temp_ptr, w, h, x - k, y)); } *(out_pix_ptr++) = saturate((int)result, 256); } } // compose output filename char out_path[MAX_PATH_LEN + 1]; snprintf(out_path, MAX_PATH_LEN, "%s.out.gray", argv[i]); // write data to output file FILE * const out_file = fopen(out_path, "wb"); if(NULL == out_file || 1 != fwrite(data_ptr, pix_count, 1, out_file)) { error(out_path); } fclose(out_file); } const double end = timer_ms(); // print total time printf("time: %f ms, %d images => %f ms/image\n", end - begin, argn - 4, (end - begin) / (argn - 4)); // cleanup free(temp_ptr); free(data_ptr); return 0; }
/*tga2gif(ac, av) int ac; char **av;*/ tga2gif(char *filename) { int i, w, h, c, r, g, b; long total; char file[80], /* root of file name */ infile[80], /* input file name */ outfile[80], /* gif file name */ palfile[80]; /* palette file name */ int (*grab_a_pix)(), get_pix(), get_pix_fs(); // strcpy(name, strrchr(filename[0], PATH_SEPARATOR)+1); /* get rid of the path */ // *strchr(name, '.') = 0; /* get rid of the .exe */ // strlwr(name); /* gimmee lower case */ palfile[0] = 0; /* NULL string */ initdata(); grab_a_pix = get_pix; /* default, non dithered function for gif */ /*if(ac < 2) usage(name);*/ infile[0] = '\0'; //for(i=1; i<ac; i++) { /* loop through command line args */ strlwr(filename); strcpy(file, filename); strcpy(infile, filename); strcpy(outfile, filename); strcat(infile, ".tga"); strcat(outfile, ".gif"); //} /* end of i loop through args */ /* Open image file for reading */ infp = fopen(infile, READ_MODE); if(!infp) { fprintf(stderr, "Error opening file %s for input.\n", infile); exit(1); } /* Read targa header. 3rd byte should be 2 signifying a type 2 targa file. Get resolution. */ my_getc(infp); my_getc(infp); if(my_getc(infp) != 2) { fprintf(stderr, "Sorry, but this program only works for type 2 Targa files.\n"); exit(1); } for(i=3; i<12; i++) { my_getc(infp); } /* get res */ xres = my_getc(infp); xres += my_getc(infp)<<8; yres = my_getc(infp); yres += my_getc(infp)<<8; /* get last two bytes of the header */ my_getc(infp); my_getc(infp); printf("image size : %d x %d\n", xres, yres); /* Put width of image in w */ w = xres; width = w; /* Put height of image in h */ h = yres; height = h; /* read in image and build tree if we need to */ if(method==POP || method==MEDIAN_BOX) { printf("Building tree.\n total colors = "); total_pixels = total_colors; total = (long)w * (long)h; while(total > 0) { /* Read color run length */ c = 1; if(c==0) c = 1024; /* read an rgb triple */ b = my_getc(infp); g = my_getc(infp); r = my_getc(infp); add_color(r>>2, g>>2, b>>2, c); /* add to tree */ total -= c; if(total_pixels != total_colors) { if((total_colors % (PRINT_STEP<<2)) == 0) printf("%8ld\b\b\b\b\b\b\b\b", total_colors); total_pixels = total_colors; } } printf("%8ld\b\b\b\b\b\b\b\b", total_colors); printf("\n"); }