X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=apps%2Fsilcmap%2Fsilcmap_bitmap.c;fp=apps%2Fsilcmap%2Fsilcmap_bitmap.c;h=0000000000000000000000000000000000000000;hb=72c2de619079457f7a68100eb13385275a424a23;hp=6440f88ddcc8e6208d3263f2ad5ce07428cca756;hpb=e7b6c157b80152bf9fb9266e6bdd93f9fb0db776;p=runtime.git diff --git a/apps/silcmap/silcmap_bitmap.c b/apps/silcmap/silcmap_bitmap.c deleted file mode 100644 index 6440f88d..00000000 --- a/apps/silcmap/silcmap_bitmap.c +++ /dev/null @@ -1,500 +0,0 @@ -/* - - silcmap_bitmap.c - - Author: Pekka Riikonen - - Copyright (C) 2003 - 2004 Pekka Riikonen - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - -*/ - -#include "silcincludes.h" -#include "silcclient.h" -#include -#include "silcmap.h" -#include "data.h" - -/******* Bitmap Routines *****************************************************/ - -/* Load a bitmap file. The file is the map image that is loaded into - the SilcMap context. This is no perfect PPM loader. */ - -bool silc_map_load_ppm(SilcMap map, const char *filename) -{ - int fd; - char type[3]; - unsigned char header[80]; - int ret, retval = TRUE, i; - - SILC_LOG_DEBUG(("Load PPM '%s'", 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 = sscanf(header, "%s %ld %ld %ld\n", type, - (unsigned long *)&map->width, - (unsigned long *)&map->height, - (unsigned long *)&map->maxcolor); - if (ret < 4) { - fprintf(stderr, "Invalid PPM file"); - retval = FALSE; - 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 = read(fd, map->bitmap, map->bitmap_size); - if (ret < 0) { - fprintf(stderr, "read: %s\n", strerror(errno)); - retval = FALSE; - goto out; - } - - out: - close(fd); - return retval; -} - -/* Write the map into a bitmap file. */ - -bool silc_map_write_ppm(SilcMap map, const char *filename) -{ - int fd; - int retval = TRUE; - char header[80]; - - SILC_LOG_DEBUG(("Write PPM '%s'", 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 */ - 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 */ - write(fd, map->bitmap, map->bitmap_size); - close(fd); - - return retval; -} - -/* Cut the map into a `width' * `height' size chunk at `x' and `y'. This - returns the allocated map bitmap into `ret_bitmap'. The original map - is not modified. */ - -bool silc_map_cut(SilcMap map, SilcInt32 x, SilcInt32 y, - SilcUInt32 width, SilcUInt32 height, - SilcMap *ret_map) -{ - int i; - - SILC_LOG_DEBUG(("cut")); - - /* Sanity checks */ - if (height > map->height - y) { - fprintf(stderr, "Requesting too much height: %ld\n", - (unsigned long)height); - return FALSE; - } - if (width > map->width - x) { - fprintf(stderr, "Requesting too much width: %ld\n", - (unsigned long)width); - return FALSE; - } - - /* Compute coordinates in the bitmap */ - y = (map->width * 3) * y; - x = (x * 3); - - /* Allocate new SilcMap context */ - *ret_map = silc_calloc(1, sizeof(**ret_map)); - (*ret_map)->width = width; - (*ret_map)->height = height; - (*ret_map)->maxcolor = map->maxcolor; - (*ret_map)->bitmap_size = (width * 3) * height; - (*ret_map)->bitmap = silc_malloc((*ret_map)->bitmap_size); - - /* Copy the requested area */ - for (i = 0; i < height; i++) { - memcpy((*ret_map)->bitmap + (i * width * 3), - map->bitmap + y + x, width * 3); - - /* Next line */ - y += (map->width * 3); - } - - return TRUE; -} - -/* Draw a bitmap indicated by `bitmap' of size of `width' * 'height' - into the SilcMap context into the coordinates `x' and `y' (the upper left - corner of the bitmap will be at x and y). The `bitmap' must be RGB - color bitmap. */ - -bool silc_map_draw(SilcMap map, - SilcInt32 x, SilcInt32 y, - const unsigned char *bitmap, - SilcUInt32 width, SilcUInt32 height) -{ - int i, k; - unsigned char val; - - /* Compute coordinates in the bitmap */ - y = (map->width * 3) * y; - x = (x * 3); - - /* Draw the bitmap into the map bitmap */ - for (i = 0; i < height; i++) { - for (k = 0; k < width; k++) { - val = bitmap[i * (width * 3) + (k * 3)]; - map->bitmap[y + x + (k * 3) ] = val; /* R */ - - val = bitmap[i * (width * 3) + (k * 3) + 1]; - map->bitmap[y + x + (k * 3) + 1] = val; /* G */ - - val = bitmap[i * (width * 3) + (k * 3) + 2]; - map->bitmap[y + x + (k * 3) + 2] = val; /* B */ - } - - /* Next line */ - y += (map->width * 3); - } - - return TRUE; -} - -/* Same as silc_map_draw but the `bitmap' is a grayscale bitmap - and the RGB color information is provided as argument to this function. */ - -bool silc_map_draw_raw(SilcMap map, - SilcInt32 x, SilcInt32 y, - const unsigned char *bitmap, - SilcUInt32 width, SilcUInt32 height, - SilcInt16 r, SilcInt16 g, SilcInt16 b) -{ - int i, k; - unsigned char val; - - /* Compute coordinates in the bitmap */ - y = (map->width * 3) * y; - x = (x * 3); - - /* Draw the bitmap into the map bitmap */ - for (i = 0; i < height; i++) { - for (k = 0; k < width; k++) { - val = bitmap[i * width + k]; - if (val != 0) { - map->bitmap[y + x + (k * 3) ] = r; /* R */ - map->bitmap[y + x + (k * 3) + 1] = g; /* G */ - map->bitmap[y + x + (k * 3) + 2] = b; /* B */ - } - } - - /* Next line */ - y += (map->width * 3); - } - - return TRUE; -} - -/* Draw a straight line between points a and b. The coordinates for the - points are provided as arguments. The `width' is the line width in - pixels. The RGB color for the line can be provided too. Implements - DDA algorithm. */ - -bool silc_map_draw_line(SilcMap map, SilcUInt32 width, - SilcInt32 a_x, SilcInt32 a_y, - SilcInt32 b_x, SilcInt32 b_y, - SilcInt16 r, SilcInt16 g, SilcInt16 b) -{ - unsigned char p[3] = { r, g, b }; - int xdiff, ydiff, i; - double x, y, slox, sloy; - - SILC_LOG_DEBUG(("draw_line")); - - /* Compute the difference of points */ - xdiff = b_x - a_x; - ydiff = b_y - a_y; - if (!xdiff && !ydiff) - return FALSE; - - /* Draw the line */ - if (abs(xdiff) > abs(ydiff)) { - sloy = (double)ydiff / (double)xdiff; - y = a_y + 0.5; /* rounding */ - if (xdiff > 0) { - for (x = a_x; x <= b_x; x++) { - for (i = 0; i < width; i++) - silc_map_draw(map, x + i, floor(y), p, 1, 1); - y += sloy; - } - } else { - for (x = a_x; x >= b_x; x--) { - for (i = 0; i < width; i++) - silc_map_draw(map, x + i, floor(y), p, 1, 1); - y -= sloy; - } - } - } else { - slox = (double)xdiff / (double)ydiff; - x = a_x + 0.5; /* rounding */ - if (ydiff > 0) { - for (y = a_y; y <= b_y; y++) { - for (i = 0; i < width; i++) - silc_map_draw(map, floor(x + i), y, p, 1, 1); - x += slox; - } - } else { - for (y = a_y; y >= b_y; y--) { - for (i = 0; i < width; i++) - silc_map_draw(map, floor(x + i), y, p, 1, 1); - x -= slox; - } - } - } - - return TRUE; -} - -/* Print the text string `text' on the bitmap at `x' and `y'. The color - for the text can be provided as argument. */ - -bool silc_map_draw_text(SilcMap map, const char *text, - SilcInt32 x, SilcInt32 y, - SilcInt16 r, SilcInt16 g, SilcInt16 b) -{ - int k, w; - int c; - - SILC_LOG_DEBUG(("draw_text")); - - /* Write the text. */ - w = 0; - for (k = 0; k < strlen(text); k++) { - c = text[k] - 33; - silc_map_draw_raw(map, x + w, y, - map->font.font[c].data, - map->font.font[c].width, - map->font.height, r, g, b); - w += map->font.font[c].width; - } - - return TRUE; -} - -/* Draw circle on the bitmap map at `x' and `y'. The center of the - circle will be at the `x' and `y'. If the `label' is provided the - text will appear with the circle at `lposx' and `lposy' in relation - with the circle. */ - -bool silc_map_draw_circle(SilcMap map, SilcInt32 x, SilcInt32 y, - SilcInt16 r, SilcInt16 g, SilcInt16 b, - const char *label, SilcInt32 lposx, SilcInt32 lposy, - SilcInt16 lr, SilcInt16 lg, SilcInt16 lb) -{ - bool ret; - - SILC_LOG_DEBUG(("draw_circle")); - - y = y - (silc_map_circle.height / 2); - x = x - (silc_map_circle.width / 2); - - ret = silc_map_draw_raw(map, x, y, - silc_map_circle.data, - silc_map_circle.width, silc_map_circle.height, - r, g, b); - if (!ret) - return FALSE; - - if (label) - ret = silc_map_draw_text(map, label, x + lposx, y - lposy, lr, lg, lb); - - return ret; -} - -/* Draw rectangle on the bitmap map at `x' and `y'. The center of the - rectangle will be at the `x' and `y'. If the `label' is provided the - text will appear with the circle at `lposx' and `lposy' in relation - with the circle. */ - -bool silc_map_draw_rectangle(SilcMap map, SilcInt32 x, SilcInt32 y, - SilcInt16 r, SilcInt16 g, SilcInt16 b, - const char *label, - SilcInt32 lposx, SilcInt32 lposy, - SilcInt16 lr, SilcInt16 lg, SilcInt16 lb) -{ - bool ret; - - SILC_LOG_DEBUG(("draw_rectangle")); - - y = y - (silc_map_rectangle.height / 2); - x = x - (silc_map_rectangle.width / 2); - - ret = silc_map_draw_raw(map, x, y, - silc_map_rectangle.data, silc_map_rectangle.width, - silc_map_rectangle.height, - r, g, b); - if (!ret) - return FALSE; - - if (label) - ret = silc_map_draw_text(map, label, x + lposx, y - lposy, lr, lg, lb); - - return ret; -} - -/* Parses the degree position string. For example, longitude 40 23 10, - as in 40 degrees, 23 minutes and 10 seconds east. Negative degree is to - West. For latitude positive is north and negative south. */ - -double silc_map_parse_pos(char *pos) -{ - double d = 0, m = 0, s = 0; - int ret; - - ret = sscanf(pos, "%lf %lf %lf", &d, &m, &s); - if (ret < 1) { - fprintf(stderr, "Malfromed position string '%s'\n", pos); - return 0; - } - - if (d < 0) { - m = (m < 0 ? m : -m); - s = (s < 0 ? s : -s); - } - - return ((d < 0 ? -1 : d > 0 ? 1 : 0) * - abs(d) + (m / 60) + (s / 3600)); -} - -/* Converts longitude into position in the bitmap */ - -int silc_map_lon2x(SilcMap map, char *longitude) -{ - double meridian, aspmul, lon; - - /* Parse position string */ - lon = silc_map_parse_pos(longitude); - - /* Compute "aspect ratio multiplier" to get the position in the map. */ - meridian = (double)map->width / (double)2.0; - aspmul = meridian / 180.0; - - /* Compute the position in the bitmap map */ - return (int)(double)(meridian + (lon * aspmul)); -} - -/* Converts latitude into position in the bitmap */ - -int silc_map_lat2y(SilcMap map, char *latitude) -{ - double meridian, aspmul, lat; - - /* Parse position string */ - lat = silc_map_parse_pos(latitude); - - /* Compute "aspect ratio multiplier" to get the position in the map. */ - meridian = (double)map->height / (double)2.0; - aspmul = meridian / 90.0; - - /* Compute the position in the bitmap map */ - return (int)(double)(meridian - (lat * aspmul)); -} - -/* Parses RGB color string. */ - -bool silc_map_parse_color(const char *color, - SilcInt16 *r, SilcInt16 *g, SilcInt16 *b) -{ - int ret; - int rr, gg, bb; - - ret = sscanf(color, "%d %d %d", &rr, &gg, &bb); - if (ret < 3) { - fprintf(stderr, "Invalid color string: %s\n", color); - return FALSE; - } - - *r = (SilcInt16)rr; - *g = (SilcInt16)gg; - *b = (SilcInt16)bb; - - return TRUE; -} - -/* Loads a font file. The font file format is the following: - - height\n - width - font data - width - font data - etc. - - If this function is called multiple times the new font replaces the - old font. */ - -bool silc_map_load_font(SilcMap map, const char *filename) -{ - FILE *fp; - int i, x, y; - - /* Load the file */ - fp = fopen(filename, "r"); - if (!fp) { - fprintf(stderr, "fopen: %s: %s\n", strerror(errno), filename); - return FALSE; - } - - /* Read the font height */ - i = fscanf(fp, "%d\n", &map->font.height); - if (i < 1) - return FALSE; - - /* Read the font data */ - for (i = 0; i < 94; i++) { - map->font.font[i].width = fgetc(fp); - - for (y = 0; y < map->font.height; y++) - for (x = 0; x < map->font.font[i].width; x++) - map->font.font[i].data[(y * map->font.font[i].width) + x] = fgetc(fp); - } - - return TRUE; -}