]> rtime.felk.cvut.cz Git - eurobot/public.git/blobdiff - src/pathplan/map_2_png.c
src: raw code a changes
[eurobot/public.git] / src / pathplan / map_2_png.c
index 3b2c4b36f216c5ea6e44d4dfc75b2308caa79aaa..c68a999653b152ef07db0e693cfd6380fe53711a 100644 (file)
@@ -1,14 +1,9 @@
 /**
- * @file       map.c
- * @brief      Useful functions related map 
- * @author     Jose Maria Martin Laguna <jmmartin@etud.insa-toulouse.fr>
+ * @file       map_2_png.c
+ * @brief      Transform map to .png file
+ * @author     Matous Pokorny <pokormat@fel.cvut.cz>
  * 
- * This file contains functions to manage map.
- * The map should be accessed only by this library.
- *
- * @todo Lock the map! It necessary in multi-thread programs. If while
- * we are doing something in the map, somewhere the function
- * ShmapFree() is called, segfault occurs.
+ * This file contains function to transform map to picture (.png file). It is using libpng.
 */
 
 #include <stdlib.h>
 #include "map.h"
 #include "map_2_png.h"
 
+#define NBR_COLOR_CHANNEL 3
+
+//#define MAP_2_PNG_DBG
+
+// RGB colors used for cells
+png_color LINE_COLOR = {       // black
+       0x00,
+       0x00,
+       0x00
+}; 
+
+png_color FREE_SPACE_COLOR = { // light grey
+       0xCD,
+       0xCD,
+       0xCD
+};
+
+png_color PLAN_MASK_COLOR = {  // dark grey
+       0x99,
+       0x99,
+       0x99
+};
+
+png_color GOAL_COLOR = {       // green
+       0x00,
+       0xFF,
+       0x00
+};
+
+png_color START_COLOR = {      // red
+       0xFF,
+       0x00,
+       0x00
+};
+
+png_color PATH_COLOR = {       // dark red
+       0x8B,
+       0x25,
+       0x00
+};
+
+png_color SIMULATED_WALL_COLOR = {     // yellow
+       0xFF,
+       0xFF,
+       0x00
+};
+
+png_color INVALIDATE_AND_WALL_COLOR = {        // dark yellow
+       0xFF,
+       0xB9,
+       0x0F
+};
+
+png_color IGNORE_OBST_COLOR = {        // dark green
+       0x00,
+       0x64,
+       0x00
+};
+
+png_color MORE_THEN_ONE_FLAG = {       // dark green
+       0xFF,
+       0x00,
+       0xFF
+};
+
+png_color WALL_COLOR = {       // navy blue
+       0x19,
+       0x19,
+       0x70
+};
+
+png_color EXPANDED_CELLS_COLOR = {     // turquoise
+       0x40,
+       0xE0,
+       0xD0
+};
+
+png_color MARGIN_COLOR = {     // orange
+       0xFF,
+       0x7D,
+       0x40
+};
+
+/**
+ * @name Transform function
+ * @{
+ */
+
+/**
+ * @brief Fuction to transform map to picture (.png file)
+ * @return             1 file is not created , 0 if success.
+ * 
+ * This is an implementation of library for extended A* Algorithm 
+ * diploma thesis Collison-free Pathplannig for Mobile Robots, CTU
+ * Matous Pokorny 2012
+ */
+
 bool map_2_png(struct map *map, char* file_name)
 {
-       int width = NBR_COLOR_CHANNEL * (CELL_DIMENSION + LINE_THICK) * MAP_WIDTH; 
+       int width = (CELL_DIMENSION + LINE_THICK) * MAP_WIDTH; 
        int height = (CELL_DIMENSION + LINE_THICK) * MAP_HEIGHT;
-       png_bytep * row_pointers;
        
        int x, y;
 
@@ -35,46 +126,59 @@ bool map_2_png(struct map *map, char* file_name)
        /* create file */
         FILE *fp = fopen(file_name, "wb");
         if (!fp) {
-               printf("PATHPLAN: map_2_png: png file could not open!");
+               printf("MAP_2_PNG: map_2_png: png file could not open!");
                return true;
        }
+#ifdef MAP_2_PNG_DBG
+       printf("MAP_2_PNG: map_2_png: file %s opened\n", file_name);
+#endif
        
         /* initialize stuff */
         png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
 
         if (!png_ptr) {
-               printf("PATHPLAN: map_2_png: png stuff is not initialized!");
+               printf("MAP_2_PNG: map_2_png: png stuff is not initialized!");
                if(fclose(fp)) {
-                       printf("PATHPLAN: map_2_png: error during close the file");
+                       printf("MAP_2_PNG: map_2_png: error during close the file");
                }
                return true;
        }
 
+#ifdef MAP_2_PNG_DBG
+       printf("MAP_2_PNG: map_2_png: write struct created\n");
+#endif
+
         info_ptr = png_create_info_struct(png_ptr);
         if (!info_ptr) {
-               printf("PATHPLAN: map_2_png: png info structure is not created");
+               printf("MAP_2_PNG: map_2_png: png info structure is not created");
                if(fclose(fp)) {
-                       printf("PATHPLAN: map_2_png: error during close the file");
+                       printf("MAP_2_PNG: map_2_png: error during close the file");
                }
                return false;
        }
 
+#ifdef MAP_2_PNG_DBG
+       printf("MAP_2_PNG: map_2_png: info struct created\n");
+#endif
+       
         if (setjmp(png_jmpbuf(png_ptr))) {
-               printf("PATHPLAN: map_2_png: error during png io");
+               printf("MAP_2_PNG: map_2_png: error during png io");
                if(fclose(fp)) {
-                       printf("PATHPLAN: map_2_png: error during close the file");
+                       printf("MAP_2_PNG: map_2_png: error during close the file");
                }
                return true;
        }
 
         png_init_io(png_ptr, fp);
 
-
+#ifdef MAP_2_PNG_DBG
+       printf("MAP_2_PNG: map_2_png: png file inited\n");
+#endif
         /* write header */
         if (setjmp(png_jmpbuf(png_ptr))) {
-               printf("PATHPLAN: map_2_png: error during write png header");
+               printf("MAP_2_PNG: map_2_png: error during write png header");
                if(fclose(fp)) {
-                       printf("PATHPLAN: map_2_png: error during close the file");
+                       printf("MAP_2_PNG: map_2_png: error during close the file");
                }
                return true;
        }
@@ -83,84 +187,128 @@ bool map_2_png(struct map *map, char* file_name)
 
         png_write_info(png_ptr, info_ptr);
 
-       row_pointers = (png_bytep*) malloc(height * sizeof(png_bytep));
-        for(y=0; y<height; y++) {
-                row_pointers[y] = (png_byte*) malloc(width * sizeof(png_byte));
+#ifdef MAP_2_PNG_DBG
+       printf("MAP_2_PNG: map_2_png: info struct written in the file\n");
+#endif 
+       
+       png_byte ** row_pointers = NULL;
+       row_pointers = png_malloc (png_ptr, height * sizeof(png_byte*));
+       
+       if(!row_pointers) {
+               printf("MAP_2_PNG: map_2_png: columns of image are not created!\n");
+               return true;
        }
        
-       // fill the picture
-       png_byte *pixel = NULL;
-       png_byte *p_row_pointer = NULL;
-       png_byte *p_cell_pointer = NULL;
-       int y_i, x_j;
+#ifdef MAP_2_PNG_DBG
+       printf("MAP_2_PNG: map_2_png: column of the image is created\n");
+#endif 
+       png_color pixel;
+       bool free_space_color;
+       int x_cell, y_cell;
+       map_cell_flag_t flags;
+       for (y = 0; y < height; y++) {
+               png_byte *row = png_malloc (png_ptr, sizeof(png_byte) * width * NBR_COLOR_CHANNEL);
+               row_pointers[y] = row;
+               
+               if(!row) {
+                       printf("MAP_2_PNG: map_2_png: row of image  not created!\n");
+                       return true;
+               }
        
-       for(y = 0; y < MAP_HEIGHT; y++) {
-               for(x = 0; x < MAP_WIDTH; x++) {
+               y_cell = (int) (y / (CELL_DIMENSION + LINE_THICK));
+               for (x = 0; x < width; x++) {
+                       x_cell = (int) (x / (CELL_DIMENSION + LINE_THICK));
+                       
+                       flags = map->cells[y_cell][x_cell].flags;
                        
                        pixel = FREE_SPACE_COLOR;       // light grey color
-                       if (map->cells[y][x].flags & MAP_FLAG_PLAN_MASK) {
-                               pixel = (pixel == FREE_SPACE_COLOR) ? PLAN_MASK_COLOR : MORE_THEN_ONE_FLAG;
-                       }
-                       if (map->cells[y][x].flags & MAP_FLAG_GOAL) {
-                                pixel = (pixel == FREE_SPACE_COLOR) ? GOAL_COLOR : MORE_THEN_ONE_FLAG;         
-                       }
-                       if (map->cells[y][x].flags & MAP_FLAG_START) {
-                                pixel = (pixel == FREE_SPACE_COLOR) ? START_COLOR : MORE_THEN_ONE_FLAG;
-                       }
-                       if (map->cells[y][x].flags & MAP_FLAG_PATH) {
-                                pixel = (pixel == FREE_SPACE_COLOR) ? PATH_COLOR : MORE_THEN_ONE_FLAG;
-                       }
-                       if (map->cells[y][x].flags & MAP_FLAG_SIMULATED_WALL) {
-                                pixel = (pixel == FREE_SPACE_COLOR) ? SIMULATED_WALL_COLOR : MORE_THEN_ONE_FLAG;
-                       }
-                       if ((map->cells[y][x].flags & MAP_FLAG_WALL) && (map->cells[y][x].flags & MAP_FLAG_INVALIDATE_WALL) == 0) {
-                               pixel = (pixel == FREE_SPACE_COLOR) ? INVALIDATE_AND_WALL_COLOR : MORE_THEN_ONE_FLAG;
+                       free_space_color = true;
+                       
+                       if(((y % (CELL_DIMENSION + LINE_THICK)) >= CELL_DIMENSION) || ((x % (CELL_DIMENSION + LINE_THICK)) >= CELL_DIMENSION)){
+                               pixel = LINE_COLOR;
                        }
-                       if (map->cells[y][x].flags & MAP_FLAG_IGNORE_OBST) {
-                                pixel = (pixel == FREE_SPACE_COLOR) ? IGNORE_OBST_COLOR : MORE_THEN_ONE_FLAG;
+                       else {
+                               if (flags & MAP_FLAG_PLAN_MASK) {
+                                       pixel = (free_space_color) ? PLAN_MASK_COLOR : MORE_THEN_ONE_FLAG;
+                                       free_space_color = false;
+                               }
+                               if (flags & MAP_FLAG_GOAL) {
+                                       pixel = (free_space_color) ? GOAL_COLOR : MORE_THEN_ONE_FLAG;
+                                       free_space_color = false;
+                               }
+                               if (flags & MAP_FLAG_START) {
+                                       pixel = (free_space_color) ? START_COLOR : MORE_THEN_ONE_FLAG;
+                                       free_space_color = false;
+                               }
+                               if (flags & MAP_FLAG_PATH) {
+                                       pixel = (free_space_color) ? PATH_COLOR : MORE_THEN_ONE_FLAG;
+                                       free_space_color = false;
+                               }                               
+                               if (flags & MAP_FLAG_SIMULATED_WALL) {
+                                       pixel = (free_space_color) ? SIMULATED_WALL_COLOR : MORE_THEN_ONE_FLAG;
+                                       free_space_color = false;
+                               }
+//                             if (((flags & MAP_FLAG_WALL) && (flags & MAP_FLAG_INVALIDATE_WALL)) == 0) {
+//                                     pixel = (free_space_color) ? INVALIDATE_AND_WALL_COLOR : MORE_THEN_ONE_FLAG;
+//                                     free_space_color = false;
+//                             }
+                               if (flags & MAP_FLAG_WALL) {
+                                       pixel = (free_space_color) ? WALL_COLOR : MORE_THEN_ONE_FLAG;
+                                       free_space_color = false;
+                               }
+                               if (flags & MAP_FLAG_IGNORE_OBST) {
+                                       pixel = (free_space_color) ? IGNORE_OBST_COLOR : MORE_THEN_ONE_FLAG;
+                                       free_space_color = false;
+                               }
+                               if (flags & MAP_FLAG_PLAN_EXPANDED_CELLS) {
+                                       pixel = (free_space_color) ? EXPANDED_CELLS_COLOR : MORE_THEN_ONE_FLAG;
+                                       free_space_color = false;
+                               }
+                               if (flags & MAP_FLAG_PLAN_MARGIN) {
+                                       pixel = (free_space_color) ? MARGIN_COLOR : MORE_THEN_ONE_FLAG;
+                                       free_space_color = false;
+                               }
                        }
-                        
                        
-                       for(y_i = 0; y_i < NBR_PIXELS_IN_CELL; y_i++) {
-                               
-                               // pointer to actuall row (png)
-                               p_row_pointer = row_pointers[y * NBR_PIXELS_IN_CELL] + y_i;
-                               // pointer to actuall cell (png)
-                               p_cell_pointer = p_row_pointer + x * NBR_PIXELS_IN_CELL * NBR_COLOR_CHANNEL;
-                               
-                               for(x_j = 0; x_j < NBR_PIXELS_IN_CELL; x_j++) {
-                                       
-                                       if((x_j >= CELL_DIMENSION) || (y_i >= CELL_DIMENSION)) {
-                                               pixel = LINE_COLOR;
-                                       }
-                                       
-                                       p_cell_pointer += x_j * NBR_COLOR_CHANNEL;
-                                       *(p_cell_pointer + 1) = *(pixel + 0);   // R
-                                       *(p_cell_pointer + 1) = *(pixel + 1);   // G    
-                                       *(p_cell_pointer + 1) = *(pixel + 2);   // B
-                                       
-                               }       
-                       }
+/*#ifdef MAP_2_PNG_DBG
+                               printf("MAP_2_PNG: map_2_png: coordinates in map are %3d is smaller %d, %2d is smaller %d, color is (R, G, B) %X %X %X\n", x_cell, MAP_WIDTH, y_cell, MAP_HEIGHT, pixel.red, pixel.blue, pixel.green);
+#endif */              
+                       *row++ = pixel.red;
+                       *row++ = pixel.green;
+                       *row++ = pixel.blue;
                }
-       }         
+        }
 
+#ifdef MAP_2_PNG_DBG
+       printf("MAP_2_PNG: map_2_png: rows of the image are created\n");
+#endif 
+
+#ifdef MAP_2_PNG_DBG
+       printf("MAP_2_PNG: map_2_png: image is created\n");
+#endif
         /* write bytes */
         if (setjmp(png_jmpbuf(png_ptr))) {
-               printf("PATHPLAN: map_2_png: error during write bytes");
+               printf("MAP_2_PNG: map_2_png: error during write bytes");
                if(fclose(fp)) {
-                       printf("PATHPLAN: map_2_png: error during close the file");
+                       printf("MAP_2_PNG: map_2_png: error during close the file");
                }
                return true;
        }
        
+#ifdef MAP_2_PNG_DBG
+       printf("MAP_2_PNG: map_2_png: bytes are written\n");
+#endif
         png_write_image(png_ptr, row_pointers);
-
+       
+#ifdef MAP_2_PNG_DBG
+       printf("MAP_2_PNG: map_2_png: image is written\n");
+#endif
 
         /* end write */
         if (setjmp(png_jmpbuf(png_ptr))){
-               printf("PATHPLAN: map_2_png: error during write end of file");
+               printf("MAP_2_PNG: map_2_png: error during write end of file");
                if(fclose(fp)) {
-                       printf("PATHPLAN: map_2_png: error during close the file");
+                       printf("MAP_2_PNG: map_2_png: error during close the file");
                }
                return true;
        }
@@ -172,9 +320,16 @@ bool map_2_png(struct map *map, char* file_name)
                 free(row_pointers[y]);
         free(row_pointers);
 
+#ifdef MAP_2_PNG_DBG
+       printf("MAP_2_PNG: map_2_png: memory is free\n");
+#endif
+       
         if(fclose(fp)) {
-               printf("PATHPLAN: map_2_png: error during close the file");
+               printf("MAP_2_PNG: map_2_png: error during close the file");
        }
        
+#ifdef MAP_2_PNG_DBG
+       printf("MAP_2_PNG: map_2_png: file is closed, return from function\n");
+#endif
        return false;
 }