Exemple #1
0
void action_decompress_image(void)
{
	uint64_t data_len;
	uint8_t* data = read_file(input_path, &data_len);

	if (!data) {
		printf("ERROR: Can't load file %s!\n", input_path);
		exit(EXIT_FAILURE);
	}

	if (verbose) {
		printf("Read %u bytes\n", data_len);
		printf("Decompressing...\n");
	}

	struct Image* imagep = decompress_image_full(data, data_len, 
			flags);

	if (!imagep) {
		printf("ERROR: Image decompression failure.\n");
		exit(EXIT_FAILURE);
	}

	image_save(output_path, imagep);
	image_del(imagep);
	free(data);

	if (verbose)
		printf("Image saved to %s\n", output_path);
}
Exemple #2
0
int image_save_basename(Image const * image, Property const properties[], int property_count, char const basename[], char const mime_type[])
{
    char path[256];
    name_from_pattern(basename, mime_type, path);

    return image_save(image, properties, property_count, path, mime_type);
}
Exemple #3
0
/*
 * screenshot_update()
 * Checks if the user wants to take a snapshot, and if
 * he/she does, we must do it.
 */
void screenshot_update()
{
    /* take the snapshot! (press the '=' key or the 'printscreen' key) */
    if(input_button_pressed(in, IB_FIRE1) || input_button_pressed(in, IB_FIRE2)) {
        char *file = next_available_filename();
        image_save(video_get_window_surface(), file);
        video_showmessage("'screenshots/%s' saved", basename(file));
        logfile_message("New screenshot: %s", file);
    }
}
Exemple #4
0
Fichier : video.c Projet : phako/tn
int 
video_file_save_frame(struct VideoFile* video_file, 
        const char* filename, enum ImageFormat image_format)
{
    return_if(video_file == NULL, -1);
    return_if(filename == NULL, -1);
    return_if(image_format < 0 || image_format >= IMAGE_FORMAT_COUNT, -1);

    return image_save(filename, video_file->frame_rgb->data[0],
            video_file->width, video_file->height,
            image_format);
}
static mlval ml_save_image(mlval argument)
{
  mlval global, filename;

  /* license_edition is a global C enum */

  if ((license_edition == PERSONAL) || act_as_free) {
    display_simple_message_box(
      "Saving images is not enabled in the Personal edition of MLWorks");
    return MLUNIT;
  }

  filename = FIELD(argument, 0);
  image_continuation = FIELD(argument, 1);
  declare_root(&filename, 1);

  global = global_pack(0);	/* 0 = not delivery */
  declare_root(&global, 1);

  {
    mlval old_message_level = MLSUB(gc_message_level,0);
    MLUPDATE(gc_message_level,0,MLINT(-1));
    gc_collect_all();
    MLUPDATE(gc_message_level,0,old_message_level);
  }

  argument = allocate_record(2);
  FIELD(argument, 0) = filename;
  FIELD(argument, 1) = global;
  retract_root(&filename);
  retract_root(&global);

  if(image_save(argument) == MLERROR)
    switch(errno)
    {
      case EIMPL:
      exn_raise_string(perv_exn_ref_save, "Image save not implemented");

      case EIMAGEWRITE:
      exn_raise_string(perv_exn_ref_save, "Error writing opened image file");

      case EIMAGEOPEN:
      exn_raise_string(perv_exn_ref_save, "Unable to open image file");

      default:
      exn_raise_string(perv_exn_ref_save, "Unexpected error from image_save()");
    }

  argument = image_continuation;
  image_continuation = MLUNIT;
  return(argument);
}
Exemple #6
0
Fichier : Taiji.c Projet : yoyao/C
int main_taiji (int argc, char *argv[])
{
	Image *image;

	image = image_new (800, 800);

	image_fill (image, 0xaa);//先将图片的数据区域填满背景色(灰色)
	draw_Taijitu (image, 300, 0);//填满背景色(灰色)后再在上面画太极图 value值是0(黑色)
	image_save (image, "taiji_6.pgm");//保存图片
	image_free (image);

	return 0;
}
Exemple #7
0
static int decode(image& ctx, const std::vector<std::string>& inp_filenames,
        const std::string& fec_filename, std::string& out_filename)
{
    const std::string& inp_filename = inp_filenames.front();

    if (ctx.inplace && ctx.sparse) {
        FATAL("invalid parameters: inplace cannot be used with sparse "
            "files\n");
    }

    if (!image_ecc_load(fec_filename, &ctx) ||
            !image_load(inp_filenames, &ctx, !out_filename.empty())) {
        FATAL("failed to read input\n");
    }

    if (ctx.inplace) {
        INFO("correcting '%s' using RS(255, %d) from '%s'\n",
            inp_filename.c_str(), ctx.rs_n, fec_filename.c_str());

        out_filename = inp_filename;
    } else {
        INFO("decoding '%s' to '%s' using RS(255, %d) from '%s'\n",
            inp_filename.c_str(),
            out_filename.empty() ? out_filename.c_str() : "<none>", ctx.rs_n,
            fec_filename.c_str());
    }

    if (ctx.verbose) {
        INFO("\traw fec size: %u\n", ctx.fec_size);
        INFO("\tblocks: %" PRIu64 "\n", ctx.blocks);
        INFO("\trounds: %" PRIu64 "\n", ctx.rounds);
    }

    if (!image_process(decode_rs, &ctx)) {
        FATAL("failed to process input\n");
    }

    if (ctx.rv) {
        INFO("corrected %" PRIu64 " errors\n", ctx.rv);
    } else {
        INFO("no errors found\n");
    }

    if (!out_filename.empty() && !image_save(out_filename, &ctx)) {
        FATAL("failed to write output\n");
    }

    image_free(&ctx);
    return 0;
}
int main (int argc, char *argv[]) {
	
	Image *image;
	image = image_new (2048, 2048);
	image_fill (image, 0);

	draw_circle (image,  256,  256, 256,  50); // Draw Label 1
	draw_circle (image,  256, 1792, 256,  50); // Draw Label 2
	draw_circle (image, 1792,  256, 256,  50); // Draw Label 3
	draw_circle (image, 1792, 1792, 256,  50); // Draw Label 4
	draw_circle (image, 1024, 1024, 512, 100); // Draw Label 5

	image_save (image, "sample.intensities.pgm");
	image_free (image);

	return 0;
}
Exemple #9
0
int screen_save_part(string filename,unsigned x,unsigned y,unsigned w,unsigned h) { //Assumes native integers are little endian
	unsigned sz = w*h;

	string ext = enigma::image_get_format(filename);

	unsigned char *rgbdata = new unsigned char[sz*4];
	GLint prevFbo;
	glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &prevFbo);
	glPixelStorei(GL_PACK_ALIGNMENT, 1);
 	glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
	glReadPixels(x,window_get_region_height_scaled()-h-y,w,h, GL_RGBA, GL_UNSIGNED_BYTE, rgbdata);
	glBindFramebuffer(GL_FRAMEBUFFER_EXT, prevFbo);

	int ret = image_save(filename, rgbdata, w, h, w, h, false);

	delete[] rgbdata;
	return ret;
}
Exemple #10
0
static mlval ml_save_image(mlval argument)
{
  mlval global, filename;

  filename = FIELD(argument, 0);
  image_continuation = FIELD(argument, 1);
  declare_root(&filename, 1);

  global = global_pack(0);	/* 0 = not delivery */
  declare_root(&global, 1);

  {
    mlval old_message_level = MLSUB(gc_message_level,0);
    MLUPDATE(gc_message_level,0,MLINT(-1));
    gc_collect_all();
    MLUPDATE(gc_message_level,0,old_message_level);
  }

  argument = allocate_record(2);
  FIELD(argument, 0) = filename;
  FIELD(argument, 1) = global;
  retract_root(&filename);
  retract_root(&global);

  if(image_save(argument) == MLERROR)
    switch(errno)
    {
      case EIMPL:
      exn_raise_string(perv_exn_ref_save, "Image save not implemented");

      case EIMAGEWRITE:
      exn_raise_string(perv_exn_ref_save, "Error writing opened image file");

      case EIMAGEOPEN:
      exn_raise_string(perv_exn_ref_save, "Unable to open image file");

      default:
      exn_raise_string(perv_exn_ref_save, "Unexpected error from image_save()");
    }

  argument = image_continuation;
  image_continuation = MLUNIT;
  return(argument);
}
Exemple #11
0
int screen_save(string filename) //Assumes native integers are little endian
{
  unsigned int w=window_get_width(),h=window_get_height(),sz=w*h;

  string ext = enigma::image_get_format(filename);

  unsigned char *rgbdata = new unsigned char[sz*4];
  GLint prevFbo;
  glGetIntegerv(GL_FRAMEBUFFER_BINDING, &prevFbo);
  glPixelStorei(GL_PACK_ALIGNMENT, 1);
   glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
  glReadPixels(0,0,w,h, GL_RGBA, GL_UNSIGNED_BYTE, rgbdata);
  glBindFramebuffer(GL_DRAW_FRAMEBUFFER, prevFbo);

  int ret = image_save(filename, rgbdata, w, h, w, h, false);

  delete[] rgbdata;
  return ret;
}
int main (int argc, char *argv[]) {
	
	Image *image;
	image = image_new (300, 246);
	image_fill (image, 0);

	draw_label (image,   50,   50,   70,   70,  60); // Draw Label 1
	draw_label (image,   30,  100,   60,  130,  80); // Draw Label 2
	draw_label (image,  150,  120,  180,  150, 100); // Draw Label 3
	draw_label (image,  150,   10,  180,   30, 120); // Draw Label 4
	draw_label (image,  110,   80,  130,  110, 140); // Draw Label 5
	draw_label (image,   70,  150,  100,  170, 160); // Draw Label 6
	draw_label (image,  100,  220,  130,  240, 180); // Draw Label 7
	draw_label (image,  200,   50,  240,   90, 200); // Draw Label 8
	draw_label (image,  270,  100,  300,  130, 220); // Draw Label 9
	draw_label (image,  240,  170,  270,  200, 240); // Draw Label 10

	image_save (image, "label.pgm");
	image_free (image);

	return 0;
}
static gboolean process_image(gpointer parent)
{
    gboolean success = TRUE;
    
    image_output imageout = (image_output)g_malloc(sizeof(struct imageout_str));
    char* orig_filename = NULL;
    char* orig_basename = NULL;
    char* orig_file_ext = NULL;
    char* output_file_comp = NULL;
    
    // store original file path and name 
    orig_filename = g_slist_nth (bimp_input_filenames, processed_count)->data;
    orig_basename = g_strdup(comp_get_filename(orig_filename)); 
    
    // store original extension and check error cases 
    orig_file_ext = g_strdup(strrchr(orig_basename, '.'));
    if (orig_file_ext == NULL) {
        /* under Linux, GtkFileChooser lets to pick an image file without extension, but GIMP cannot 
         * save it back if its format remains unchanged. Operation can continue only if a MANIP_CHANGEFORMAT
         * is present */
        if (list_contains_changeformat) {
            orig_file_ext = g_malloc0(sizeof(char));
        }        
        else {
            bimp_show_error_dialog(g_strdup_printf(_("Can't save image \"%s\": input file has no extension.\nYou can solve this error by adding a \"Change format or compression\" step"), orig_basename), bimp_window_main);
            success = FALSE;
            goto process_end;
        }
    }
    else if (g_ascii_strcasecmp(orig_file_ext, ".svg") == 0 && !list_contains_changeformat) {
        bimp_show_error_dialog(g_strdup_printf(_("GIMP can't save %s back to its original SVG format.\nYou can solve this error by adding a \"Change format or compression\" step"), orig_basename), bimp_window_main);
        success = FALSE;
        goto process_end;
    }
    
    g_print("\nWorking on file %d of %d (%s)\n", processed_count + 1, total_images, orig_filename);
    bimp_progress_bar_set(((double)processed_count)/total_images, g_strdup_printf(_("Working on file \"%s\"..."), orig_basename));

    // rename and save process... 
    orig_basename[strlen(orig_basename) - strlen(orig_file_ext)] = '\0'; // remove extension from basename 
    
    // check if a rename pattern is defined 
    if(list_contains_rename) {
        g_print("Applying RENAME...\n");
        apply_rename((rename_settings)(bimp_list_get_manip(MANIP_RENAME))->settings, imageout, orig_basename);
    }
    else {
        imageout->filename = orig_basename;
    }

    // To keep the folder hierarchy 
    if (common_folder_path == NULL)    {
        // Not selected or required, everything goes into the same destination folder
        output_file_comp = g_malloc0(sizeof(char));
    }
    else {
        // keep folders to add to output path
        output_file_comp = 
            g_strndup(&orig_filename[strlen(common_folder_path)+1],
            strlen(orig_filename)-(strlen(common_folder_path)+1)
            -strlen(orig_basename)-strlen(orig_file_ext)); 
    }
    
    if (strlen(output_file_comp) > 0) {
#ifdef _WIN32        
        // Clean output_file_comp
        // Should only be concerned for ':' in Drive letter
        int i;
        for (i = 0; i < strlen(output_file_comp); ++i)
            if ( output_file_comp[i] == ':' )
                output_file_comp[i] = '_';
#endif
        // Create path if needed
        g_mkdir_with_parents(
            g_strconcat(bimp_output_folder, FILE_SEPARATOR_STR, output_file_comp, NULL), 
            0777
        );
    }
    
    // save the final image in output dir with proper format and params 
    format_type final_format = -1;
    format_params params = NULL;
    
    if(list_contains_changeformat) {
        changeformat_settings settings = (changeformat_settings)(bimp_list_get_manip(MANIP_CHANGEFORMAT))->settings;
        final_format = settings->format;
        params = settings->params;

        g_print("Changing FORMAT to %s\n", format_type_string[final_format][0]);
        imageout->filename = g_strconcat(imageout->filename, ".", format_type_string[final_format][0], NULL); // append new file extension 
        imageout->filepath = g_strconcat(bimp_output_folder, FILE_SEPARATOR_STR, output_file_comp, imageout->filename, NULL); // build new path 
    }
    // TO CHECK what apply_userdef does once coded 

    else if (list_contains_savingplugin) {
        // leave filename without extension and proceed calling each saving plugin
        imageout->filename = g_strconcat(imageout->filename, ".dds", NULL);
        imageout->filepath = g_strconcat(bimp_output_folder, FILE_SEPARATOR_STR, output_file_comp, imageout->filename, NULL); // build new path 
        
        GSList *iterator = NULL;
        manipulation man;
        for (iterator = bimp_selected_manipulations; iterator; iterator = iterator->next) {
            man = (manipulation)(iterator->data);
            if (man->type == MANIP_USERDEF && strstr(((userdef_settings)(man->settings))->procedure, "-save") != NULL) {
                /* found a saving plugin, execute it
                // TODO!!!! This won't work yet, we need a way to extract the file extension managed by the selected saving plugin
                 * e.g. "file-dds-save" -> "dds" (don't do it with regexp on plugin's name... too easy...) */
                apply_userdef((userdef_settings)(man->settings), imageout);
            }
        }
    }
    else {
        // if not specified, save in original format 
        imageout->filename = g_strconcat(imageout->filename, orig_file_ext, NULL); // append old file extension     
        imageout->filepath = g_strconcat(bimp_output_folder, FILE_SEPARATOR_STR, output_file_comp, imageout->filename, NULL); // build new path         
        final_format = -1;    
    }
    
    // check if writing possible 
    gboolean will_overwrite = FALSE;
    if (bimp_opt_alertoverwrite != BIMP_OVERWRITE_SKIP_ASK) {
        // file already exists ?
        will_overwrite = g_file_test(imageout->filepath, G_FILE_TEST_IS_REGULAR);        
        if (will_overwrite) {
            // "Don't overwrite" without confirmation
            if (bimp_opt_alertoverwrite == BIMP_DONT_OVERWRITE_SKIP_ASK) {
                g_print("Destination file already exists and won't be overwritten\n");
                goto process_end;
            }
            else {
                // Ask what to do
                int ow_res = overwrite_result(imageout->filepath, parent);
                if (ow_res == 0) {
                    g_print("Destination file already exists and user select to don't overwrite\n");
                    goto process_end;
                }
            }
        }
    }
    
    // apply all the main manipulations 
    bimp_apply_drawable_manipulations(imageout, (gchar*)orig_filename, (gchar*)orig_basename); 
    
    time_t mod_time = -1;
    if (will_overwrite && bimp_opt_keepdates) {
        // I must keep the dates even if the file has been overwritten
        mod_time = get_modification_time(imageout->filepath);
        if (mod_time == -1) g_print("An error occurred when retrieving the modification date of file.\n");
    }
    
    // Save 
    g_print("Saving file %s in %s\n", imageout->filename, imageout->filepath);
    image_save(final_format, imageout, params);
    
    if (will_overwrite && bimp_opt_keepdates && mod_time > -1) {
        // replace with the old dates
        int res = set_modification_time(imageout->filepath, mod_time);
        if (res == -1) g_print("An error occurred when replacing the modification date of file.\n");
    }

    gimp_image_delete(imageout->image_id); // is it useful? 
    
process_end:

    g_free(orig_basename);
    g_free(orig_file_ext);
    g_free(output_file_comp);
    g_free(imageout->filename);
    g_free(imageout->filepath);
    g_free(imageout);

    processed_count++;
    if (success) success_count++; 
    
    // TODO: errors check here 
    if (!bimp_is_busy) {
        bimp_progress_bar_set(0.0, _("Operations stopped"));
        g_print("\nStopped, %d files processed.\n", processed_count);
        return FALSE;
    }
    else {
        if (processed_count == total_images) {
            int errors_count = processed_count - success_count;
            bimp_progress_bar_set(1.0, g_strdup_printf(_("End, all files have been processed with %d errors"), errors_count));
            g_print("\nEnd, %d files have been processed with %d errors.\n", processed_count, errors_count);
            
            bimp_set_busy(FALSE);
            
            return FALSE;
        }
        else {
            return TRUE;
        }
    }
}
Exemple #14
0
void menu_func (int value)
{
	// variables used in the switch statement
	char filename[MAX_LINE];

	switch (value)
	{
	case M_QUIT:  // enum #0
		exit(0);
		break;



	case M_HELP:  // enum #1
		menu_help();
		break;



	case M_FILE_OPEN:   // enum #2
		if (!quietMode)
			cerr << "Open file (string - no spaces) : ";
		cin  >> filename;
		checkStream(cin);
		image_load(filename);
		break;


	case M_FILE_SAVE:   // enum #3
		if (!quietMode)
			cerr << "Save as (string - no spaces) : ";
		cin  >> filename;
		checkStream(cin);
		image_save(filename);
		break;


	case M_FILE_INFO:  // enum #4
		image_print_info();
		break;


	case M_FILE_REVERT:  // enum #5
		image_revert();
		break;

	case M_VIEW_PIXEL_VALUE: // enum #31
		{
			if (!currentImage) 
			{
				cerr << "Sorry, no image is loaded." << endl;
				break;
			}
			if (!quietMode)
			{
				cerr << "Current image width and height: " << currentImage->getWidth()-1 << " " 
					<< currentImage->getHeight()-1 << endl;
			}
			int x=getInt("x value of pixel to view");
			int y=getInt("y value of pixel to view");
			if (x<0 || x>=currentImage->getWidth() || y<0 || y>=currentImage->getHeight())
			{
				cerr << "Invalid pixel location." << endl;
				break;
			}
			cerr << "R: " << currentImage->getPixel(x,y,RED);
			cerr << ", G: " << currentImage->getPixel(x,y,GREEN);
			cerr << ", B: " << currentImage->getPixel(x,y,BLUE) << endl;
			break;
		}

	default:
		process_func(value);
	}
	return;
}
Exemple #15
0
int main(int argc, char* argv[])
{
    printf("[i] Start...\n");

    char file_name[] = "test.bmp";
    char* filename=file_name;

    if(argc >= 2) {
        filename = argv[1];
    }

    printf("[i] file: %s\n", filename);
	
    image* img = image_create(320, 240, 3, CV_DEPTH_8U);

    if(!img) {
        printf("[!] Error: image_create()\n");
        return -1;
    }
    image_delete(&img);

    // test image loading
    image* img2 = image_load(filename);
    printf("[i] image size: %dx%dx%d (%d)\n", img2->width, img2->height, img2->n_channels, img2->size);
    image_save(img2, "test2_load_save.bmp");

    printf("[i] == Tests == \n");
#if 1
    // copy
    printf("[i] image_copy \n");
    img = image_create(img2->width, img2->height, img2->n_channels, CV_DEPTH_8U);
    image_copy(img2, img);
    image_save(img, "test2_copy.bmp");

    // test convert image to grayscale
    printf("[i] image_convert_color \n");
    image* img_gray = image_create(img2->width, img2->height, 1, CV_DEPTH_8U);
    gettimeofday(&t0, NULL);
    image_convert_color(img2, img_gray, CV_RGB2GRAY);
    gettimeofday(&t1, NULL);
    image_save(img_gray, "test3_gray.bmp");

    // test borders detection
    printf("[i] image_thin_borders \n");
    image* img_borders = NULL;
    gettimeofday(&t2, NULL);
    image_thin_borders(img_gray, &img_borders);
    gettimeofday(&t3, NULL);
    image_save(img_borders, "test4_thin_borders.bmp");

    // min-max-loc
    printf("[i] image_min_max_loc \n");
    double _min, _max;
    gettimeofday(&t4, NULL);
    image_min_max_loc(img_gray, &_min, &_max, NULL, NULL);
    gettimeofday(&t5, NULL);
    printf("[i] min=%0.2f max=%0.2f\n", _min, _max);

    // threshold
    printf("[i] image_threshold \n");
    image* img_thr = image_create(img2->width, img2->height, 1, CV_DEPTH_8U);
    gettimeofday(&t6, NULL);
    image_threshold(img_gray, img_thr, 60);
    gettimeofday(&t7, NULL);
    image_save(img_thr, "test5_threshold.bmp");
#endif

#if 1
    // rotate180
    printf("[i] image_rotate180 \n");
    image_rotate180(img2);
    image_save(img2, "test6_rotate180.bmp");
    image_rotate180(img2);
    // reflect vertical
    printf("[i] image_reflect_vertical \n");
    image_reflect_vertical(img2);
    image_save(img2, "test7_reflect_vertical.bmp");
    image_reflect_vertical(img2);
#endif // rotate180

    int colors_count;
    cv_point center;

#if 1
    // simple resize
    printf("[i] image_resize \n");
    image *img_small = image_create(160, 120, 3, CV_DEPTH_8U);
    gettimeofday(&t8, NULL);
    image_resize(img2, img_small);
    gettimeofday(&t9, NULL);
    image_save(img_small, "test8_resize.bmp");

 //   image* img_small_gray = image_create(80, 60, 1, CV_DEPTH_8U);
//    image_convert_color(img_small, img_small_gray, CV_RGB2GRAY);

//    image* img_small_borders = NULL;
//    image_thin_borders(img_small_gray, &img_small_borders);
//    image_save(img_small_borders, "test_resize_thin_borders.bmp");

#if 1
    // k-meanes colorer
    printf("[i] image_kmeans_colorer \n");
    image* img_kmeanes = image_create(160, 120, 3, CV_DEPTH_8U);
    image* img_kmeanes_idx = image_create(160, 120, 1, CV_DEPTH_8U);

#define CLUSTER_COUNT 10
    int cluster_count = CLUSTER_COUNT;
    cv_color_cluster clusters[CLUSTER_COUNT];

    gettimeofday(&t10, NULL);
    colors_count = image_kmeans_colorer(img_small, img_kmeanes, img_kmeanes_idx, clusters, cluster_count);
    gettimeofday(&t11, NULL);

    printf("[i] colors count: %d\n", colors_count);
    image_save(img_kmeanes, "test_kmeanscolorer.bmp");

#if 0
    print_color_clusters(clusters, CLUSTER_COUNT);
    printf("[i] === colors clusters after sort:\n");
    sort_color_clusters_by_count(clusters, CLUSTER_COUNT);
    print_color_clusters(clusters, CLUSTER_COUNT);
#endif

    image_delete(&img_kmeanes);
    image_delete(&img_kmeanes_idx);
#endif // k-meanes colorer

    image_delete(&img_small);
//    image_delete(&img_small_gray);
//    image_delete(&img_small_borders);
#endif // simple resize

#if 1
    // HSV
    printf("[i] image_hsv2rgb \n");
    image* img_hsv = image_create(img2->width, img2->height, 3, CV_DEPTH_8U);
    image* img_bgr = image_create(img2->width, img2->height, 3, CV_DEPTH_8U);

    gettimeofday(&t12, NULL);
    image_rgb2hsv(img2, img_hsv);
    gettimeofday(&t13, NULL);

    image_hsv2rgb(img_hsv, img_bgr);

    image_save(img_hsv, "test9_rgb2hsv.bmp");
    image_save(img_bgr, "test9_hsv2rgb.bmp");

    image_delete(&img_hsv);
    image_delete(&img_bgr);
#endif // HSV

#if 1
    // hsv colorer
    printf("[i] image_hsv_colorer \n");
    image* img_hsv_col = image_create(img2->width, img2->height, 3, CV_DEPTH_8U);
    image* img_hsv_idx = image_create(img2->width, img2->height, 1, CV_DEPTH_8U);

#define COLORS_COUNT 10
    cv_color_cluster clusters2[COLORS_COUNT];

    gettimeofday(&t14, NULL);
    colors_count = image_hsv_colorer(img2, img_hsv_col, img_hsv_idx, clusters2, COLORS_COUNT);
    gettimeofday(&t15, NULL);

    printf("[i] colors count: %d\n", colors_count);
    image_save(img_hsv_col, "test_hsvcolorer.bmp");

#if 1
    print_color_clusters(clusters2, COLORS_COUNT);
    printf("[i] === colors clusters after sort:\n");
    sort_color_clusters_by_count(clusters2, COLORS_COUNT);
    print_color_clusters(clusters2, COLORS_COUNT);

    center = get_color_center(clusters2[0].id, img_hsv_idx);
    printf("[i] first color center:  %03d %03d\n", center.x, center.y);
    center = get_color_center(clusters2[1].id, img_hsv_idx);
    printf("[i] second color center: %03d %03d\n", center.x, center.y);
    center = get_color_center(clusters2[2].id, img_hsv_idx);
    printf("[i] third color center:  %03d %03d\n", center.x, center.y);
#endif // print_color_clusters

    image_delete(&img_hsv_col);
    image_delete(&img_hsv_idx);
#endif // hsv colorer

    printf("[i] == Performance == \n");
    print_performance("image_convert_color", t1, t0);
    print_performance("image_thin_borders", t3, t2);
    print_performance("image_min_max_loc", t5, t4);
    print_performance("image_threshold", t7, t6);
    print_performance("image_resize", t9, t8);
    print_performance("image_kmeans_colorer", t11, t10);
    print_performance("image_rgb2hsv", t13, t12);
    print_performance("image_hsv_colorer", t15, t14);

    image_delete(&img);
    image_delete(&img2);
#if 1
    image_delete(&img_gray);
    image_delete(&img_borders);
    image_delete(&img_thr);
#endif

    printf("[i] End.\n");
    return 0;
}