Optimzed bitmap reading and writing.
authorPekka Riikonen <priikone@silcnet.org>
Sat, 6 Mar 2004 17:30:53 +0000 (17:30 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Sat, 6 Mar 2004 17:30:53 +0000 (17:30 +0000)
apps/silcmap/silcmap.h
apps/silcmap/silcmap_bitmap.c
apps/silcmap/silcmap_client.c
apps/silcmap/silcmap_command.c
apps/silcmap/silcmap_html.c

index 80b6140bc22c8d77f9da0c0f6e05449ff7e60e04..a2b8e7f1998f8348f64a27e924bbda100c3898f0 100644 (file)
@@ -42,6 +42,10 @@ typedef struct {
   char *text;
   SilcInt32 lposx;
   SilcInt32 lposy;
+  char *alat;
+  char *alon;
+  char *blat;
+  char *blon;
 
   SilcInt16 r;
   SilcInt16 g;
index b05082c2ed6a2c898b0f1ddee43aab506fe11f33..6440f88ddcc8e6208d3263f2ad5ce07428cca756 100644 (file)
 
 bool silc_map_load_ppm(SilcMap map, const char *filename)
 {
-  FILE *fp;
+  int fd;
   char type[3];
-  int ret, retval = TRUE;
+  unsigned char header[80];
+  int ret, retval = TRUE, i;
 
   SILC_LOG_DEBUG(("Load PPM '%s'", filename));
 
-  fp = fopen(filename, "r");
-  if (!fp) {
-    fprintf(stderr, "fopen: %s: %s\n", strerror(errno), filename);
+  fd = open(filename, O_RDONLY, 0600);
+  if (fd < 0) {
+    fprintf(stderr, "open: %s: %s\n", strerror(errno), filename);
+    return FALSE;
+  }
+
+  /* Read file header */
+  memset(header, 0, sizeof(header));
+  ret = read(fd, (void *)header, sizeof(header) - 1);
+  if (ret < 0) {
+    fprintf(stderr, "read: %s: %s\n", strerror(errno), filename);
     return FALSE;
   }
 
   /* Read width and height */
-  ret = fscanf(fp, "%s %ld %ld %ld ", type,
+  ret = sscanf(header, "%s %ld %ld %ld\n", type,
               (unsigned long *)&map->width,
               (unsigned long *)&map->height,
               (unsigned long *)&map->maxcolor);
@@ -53,18 +62,23 @@ bool silc_map_load_ppm(SilcMap map, const char *filename)
     goto out;
   }
 
+  for (i = sizeof(header) - 1; i >= 0; i--)
+    if (header[i] == '\n' || header[i] == ' ')
+      break;
+  lseek(fd, i + 1, SEEK_SET);
+
   /* Read the picture */
   map->bitmap_size = map->width * 3 * map->height;
   map->bitmap = silc_malloc(map->bitmap_size);
-  ret = fread(map->bitmap, map->bitmap_size, 1, fp);
+  ret = read(fd, map->bitmap, map->bitmap_size);
   if (ret < 0) {
-    fprintf(stderr, "fread: %s\n", strerror(errno));
+    fprintf(stderr, "read: %s\n", strerror(errno));
     retval = FALSE;
     goto out;
   }
 
  out:
-  fclose(fp);
+  close(fd);
   return retval;
 }
 
@@ -72,26 +86,29 @@ bool silc_map_load_ppm(SilcMap map, const char *filename)
 
 bool silc_map_write_ppm(SilcMap map, const char *filename)
 {
-  FILE *fp;
+  int fd;
   int retval = TRUE;
+  char header[80];
 
   SILC_LOG_DEBUG(("Write PPM '%s'", filename));
 
-  fp = fopen(filename, "w+");
-  if (!fp) {
-    fprintf(stderr, "fopen: %s: %s\n", strerror(errno), filename);
+  fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0600);
+  if (fd < 0) {
+    fprintf(stderr, "open: %s: %s\n", strerror(errno), filename);
     return FALSE;
   }
 
   /* Write the header */
-  fprintf(fp, "P6 %ld %ld %ld\n",
+  memset(header, 0, sizeof(header));
+  snprintf(header, sizeof(header) - 1, "P6 %ld %ld %ld\n",
          (unsigned long)map->width,
          (unsigned long)map->height,
          (unsigned long)map->maxcolor);
+  write(fd, header, strlen(header));
 
   /* Write the bitmap */
-  fwrite(map->bitmap, map->bitmap_size, 1, fp);
-  fclose(fp);
+  write(fd, map->bitmap, map->bitmap_size);
+  close(fd);
 
   return retval;
 }
index c605763cd559b86b06f14f5526152a9652ca1bb4..3eec5110993601674430cacc3d51639791b1e3d0 100644 (file)
@@ -41,28 +41,28 @@ void silc_map_process_data(SilcMap map, SilcMapConnection mapconn)
   SilcInt16 r, g, b, lr, lg, lb;
   int i;
 
+  map->conn_num++;
+
   SILC_LOG_DEBUG(("Processing the data from server (%d/%d)",
                  map->conn_num, map->conns_num));
 
-  map->conn_num++;
   if (map->conn_num != map->conns_num)
     return;
 
   /* Load the map image to be processed */
-  if (!map->bitmap) {
-    if (!map->loadmap.loadmap || !map->loadmap.filename) {
-      silc_schedule_task_add(map->client->schedule, 0,
-                            silc_map_process_done, map, 0, 1,
-                            SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
-      return;
-    }
+  silc_free(map->bitmap);
+  if (!map->loadmap.loadmap || !map->loadmap.filename) {
+    silc_schedule_task_add(map->client->schedule, 0,
+                          silc_map_process_done, map, 0, 1,
+                          SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
+    return;
+  }
 
-    if (!silc_map_load_ppm(map, map->loadmap.filename)) {
-      silc_schedule_task_add(map->client->schedule, 0,
-                            silc_map_process_done, map, 0, 1,
-                            SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
-      return;
-    }
+  if (!silc_map_load_ppm(map, map->loadmap.filename)) {
+    silc_schedule_task_add(map->client->schedule, 0,
+                          silc_map_process_done, map, 0, 1,
+                          SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
+    return;
   }
 
   /* Now process all received data one by one */
@@ -80,6 +80,15 @@ void silc_map_process_data(SilcMap map, SilcMapConnection mapconn)
     /* Execute the map commands */
     silc_dlist_start(mapconn->commands);
     while ((cmd = silc_dlist_get(mapconn->commands)) != SILC_LIST_END) {
+      if (cmd->alon && cmd->alat) {
+       cmd->x = silc_map_lon2x(map, cmd->alon);
+       cmd->y = silc_map_lat2y(map, cmd->alat);
+       if (cmd->blon && cmd->blat) {
+         cmd->x2 = silc_map_lon2x(map, cmd->blon);
+         cmd->y2 = silc_map_lat2y(map, cmd->blat);
+       }
+      }
+
       if (cmd->cut) {
        if (silc_map_cut(map, cmd->x, cmd->y, cmd->width,
                         cmd->height, &ret_map)) {
@@ -150,7 +159,6 @@ void silc_map_process_data(SilcMap map, SilcMapConnection mapconn)
     /* Write uptime reliability data */
     if (map->writerel.writerel)
       silc_map_writerel(map, mapconn);
-
   }
 
   SILC_LOG_DEBUG(("All connections processed"));
@@ -159,6 +167,10 @@ void silc_map_process_data(SilcMap map, SilcMapConnection mapconn)
   if (map->writemap.writemap)
     silc_map_write_ppm(map, map->writemap.filename);
   for (i = 0; i < map->cut_count; i++) {
+    if (map->cut[i].alon && map->cut[i].alat) {
+      map->cut[i].x = silc_map_lon2x(map, map->cut[i].alon);
+      map->cut[i].y = silc_map_lat2y(map, map->cut[i].alat);
+    }
     if (silc_map_cut(map, map->cut[i].x, map->cut[i].y, map->cut[i].width,
                     map->cut[i].height, &ret_map)) {
       silc_map_write_ppm(ret_map, map->cut[i].filename);
index ef548a4d800025cd04a33140c88851af7063eea7..fe0f822583a23f220e87e16b04181d5298e893f1 100644 (file)
@@ -237,7 +237,7 @@ SILC_CONFIG_CALLBACK(silc_map_cmd_server)
   SilcMap map = context;
   int retval = SILC_CONFIG_OK;
 
-  if (!map->bitmap) {
+  if (!map->loadmap.loadmap) {
     fprintf(stderr, "You must call loadmap command before server command\n");
     return SILC_CONFIG_ESILENT;
   }
@@ -366,19 +366,8 @@ SILC_CONFIG_CALLBACK(silc_map_cmd_loadmap)
 
     SILC_LOG_DEBUG(("loadmap: file: %s", filename));
 
-    /* Destroy old bitmap if loadmaped */
-    silc_free(map->bitmap);
-    map->bitmap = NULL;
-
-    /* Execute directly if there are no connections */
-    if (map->conns_num == 0) {
-      /* Load the bitmap image */
-      if (!silc_map_load_ppm(map, filename))
-       retval = SILC_CONFIG_ESILENT;
-    } else {
-      map->loadmap.filename = strdup(filename);
-      map->loadmap.writemap = TRUE;
-    }
+    map->loadmap.filename = strdup(filename);
+    map->loadmap.loadmap = TRUE;
 
     /* Cleanup */
     silc_free(filename);
@@ -408,15 +397,8 @@ SILC_CONFIG_CALLBACK(silc_map_cmd_writemap)
 
     SILC_LOG_DEBUG(("writemap: file: %s", filename));
 
-    /* Execute directly if there are no connections */
-    if (map->conns_num == 0) {
-      /* Writemap the map */
-      if (!silc_map_write_ppm(map, filename))
-       retval = SILC_CONFIG_ESILENT;
-    } else {
-      map->writemap.filename = strdup(filename);
-      map->writemap.writemap = TRUE;
-    }
+    map->writemap.filename = strdup(filename);
+    map->writemap.writemap = TRUE;
 
     /* Cleanup */
     silc_free(filename);
@@ -454,9 +436,9 @@ SILC_CONFIG_CALLBACK(silc_map_cmd_writemaphtml)
     map->writemaphtml[i].filename = filename;
     map->writemaphtml[i].text = text;
     if (lon)
-      map->writemaphtml[i].x = silc_map_lon2x(map, lon);
+      map->writemaphtml[i].alon = strdup(lon);
     if (lat)
-      map->writemaphtml[i].y = silc_map_lat2y(map, lat);
+      map->writemaphtml[i].alat = strdup(lat);
     map->writemaphtml[i].writemaphtml = TRUE;
     map->writemaphtml_count++;
 
@@ -585,8 +567,8 @@ SILC_CONFIG_CALLBACK(silc_map_cmd_cut)
        i = map->cut_count;
        map->cut = silc_realloc(map->cut, sizeof(*map->cut) * (i + 1));
        map->cut[i].filename = strdup(filename);
-       map->cut[i].x = silc_map_lon2x(map, lon);
-       map->cut[i].y = silc_map_lat2y(map, lat);
+       map->cut[i].alon = strdup(lon);
+       map->cut[i].alat = strdup(lat);
        map->cut[i].width = width;
        map->cut[i].height = height;
        map->cut[i].cut = TRUE;
@@ -599,8 +581,8 @@ SILC_CONFIG_CALLBACK(silc_map_cmd_cut)
 
       silc_dlist_add(curr_conn->commands, cmd);
       cmd->filename = strdup(filename);
-      cmd->x = silc_map_lon2x(map, lon);
-      cmd->y = silc_map_lat2y(map, lat);
+      cmd->alon = strdup(lon);
+      cmd->alat = strdup(lat);
       cmd->width = width;
       cmd->height = height;
       cmd->cut = TRUE;
@@ -676,8 +658,8 @@ SILC_CONFIG_CALLBACK(silc_map_cmd_rectangle)
       cmd->lr = lr;
       cmd->lg = lg;
       cmd->lb = lb;
-      cmd->x = silc_map_lon2x(map, lon);
-      cmd->y = silc_map_lat2y(map, lat);
+      cmd->alon = strdup(lon);
+      cmd->alat = strdup(lat);
       cmd->text = text ? strdup(text) : NULL;
       cmd->lposx = lposx;
       cmd->lposy = lposy;
@@ -766,8 +748,8 @@ SILC_CONFIG_CALLBACK(silc_map_cmd_circle)
       cmd->lr = lr;
       cmd->lg = lg;
       cmd->lb = lb;
-      cmd->x = silc_map_lon2x(map, lon);
-      cmd->y = silc_map_lat2y(map, lat);
+      cmd->alon = strdup(lon);
+      cmd->alat = strdup(lat);
       cmd->text = text ? strdup(text) : NULL;
       cmd->lposx = lposx;
       cmd->lposy = lposy;
@@ -854,10 +836,10 @@ SILC_CONFIG_CALLBACK(silc_map_cmd_line)
       cmd->r = r;
       cmd->g = g;
       cmd->b = b;
-      cmd->x = silc_map_lon2x(map, lon);
-      cmd->y = silc_map_lat2y(map, lat);
-      cmd->x2 = silc_map_lon2x(map, lon2);
-      cmd->y2 = silc_map_lat2y(map, lat2);
+      cmd->alon = strdup(lon);
+      cmd->alat = strdup(lat);
+      cmd->blon = strdup(lon2);
+      cmd->blat = strdup(lat2);
       cmd->width = width;
       cmd->draw_line = TRUE;
       cmd->color_set = color_set;
@@ -931,8 +913,8 @@ SILC_CONFIG_CALLBACK(silc_map_cmd_text)
       cmd->r = r;
       cmd->g = g;
       cmd->b = b;
-      cmd->x = silc_map_lon2x(map, lon);
-      cmd->y = silc_map_lat2y(map, lat);
+      cmd->alon = strdup(lon);
+      cmd->alat = strdup(lat);
       cmd->text = text ? strdup(text) : NULL;
       cmd->draw_text = TRUE;
       cmd->color_set = color_set;
index f565fcaab9321cae0718a04e0eec59f410a98d12..aef23d9fe973a4a15282f18ccd496a77115b5d65 100644 (file)
@@ -373,6 +373,10 @@ bool silc_map_writemaphtml(SilcMap map)
 
   for (i = 0; i < map->writemaphtml_count; i++) {
     c = &map->writemaphtml[i];
+    if (c->alon && c->alat) {
+      c->x = silc_map_lon2x(map, c->alon);
+      c->y = silc_map_lat2y(map, c->alat);
+    }
 
     /* Open for writing */
     fp = fopen(c->filename, "w+");
@@ -408,6 +412,11 @@ bool silc_map_writemaphtml(SilcMap map)
       /* Print the positions of various items on the map into the map file */
       silc_dlist_start(mapconn->commands);
       while ((cmd = silc_dlist_get(mapconn->commands)) != SILC_LIST_END) {
+       if (cmd->alon && cmd->alat) {
+         cmd->x = silc_map_lon2x(map, cmd->alon);
+         cmd->y = silc_map_lat2y(map, cmd->alat);
+       }
+
        if (cmd->draw_text) {
          w = strlen(cmd->text) * 5;
          h = map->font.height - 2;