GRASS GIS 8 Programmer's Manual  8.4.0dev(2024)-dd1a9b617b
cairodriver/read_bmp.c
Go to the documentation of this file.
1 /*!
2  \file lib/cairodriver/read_bmp.c
3 
4  \brief GRASS cairo display driver - read bitmap (lower level functions)
5 
6  (C) 2007-2008 by Lars Ahlzen and the GRASS Development Team
7 
8  This program is free software under the GNU General Public License
9  (>=v2). Read the file COPYING that comes with GRASS for details.
10 
11  \author Lars Ahlzen <lars ahlzen.com> (original contributor)
12  \author Glynn Clements
13  */
14 
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <errno.h>
19 
20 #include <grass/gis.h>
21 #include <grass/glocale.h>
22 #include "cairodriver.h"
23 
24 static unsigned int get_2(const unsigned char **q)
25 {
26  const unsigned char *p = *q;
27  unsigned int n = (p[0] << 0) | (p[1] << 8);
28 
29  *q += 2;
30  return n;
31 }
32 
33 static unsigned int get_4(const unsigned char **q)
34 {
35  const unsigned char *p = *q;
36  unsigned int n = (p[0] << 0) | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
37 
38  *q += 4;
39  return n;
40 }
41 
42 static int read_bmp_header(const unsigned char *p)
43 {
44  if (*p++ != 'B')
45  return 0;
46  if (*p++ != 'M')
47  return 0;
48 
49  if (get_4(&p) != (unsigned int)HEADER_SIZE + ca.width * ca.height * 4)
50  return 0;
51 
52  get_4(&p);
53 
54  if (get_4(&p) != HEADER_SIZE)
55  return 0;
56 
57  if (get_4(&p) != 40)
58  return 0;
59 
60  if (get_4(&p) != (unsigned int)ca.width)
61  return 0;
62  if (get_4(&p) != (unsigned int)-ca.height)
63  return 0;
64 
65  get_2(&p);
66  if (get_2(&p) != 32)
67  return 0;
68 
69  if (get_4(&p) != 0)
70  return 0;
71  if (get_4(&p) != (unsigned int)ca.width * ca.height * 4)
72  return 0;
73 
74  get_4(&p);
75  get_4(&p);
76  get_4(&p);
77  get_4(&p);
78 
79  return 1;
80 }
81 
82 void cairo_read_bmp(void)
83 {
84  unsigned char header[HEADER_SIZE];
85  FILE *input;
86 
87  input = fopen(ca.file_name, "rb");
88  if (!input)
89  G_fatal_error(_("Cairo: unable to open input file <%s>"), ca.file_name);
90 
91  if (fread(header, sizeof(header), 1, input) != 1)
92  G_fatal_error(_("Cairo: invalid input file <%s>"), ca.file_name);
93 
94  if (!read_bmp_header(header))
95  G_fatal_error(_("Cairo: Invalid BMP header for <%s>"), ca.file_name);
96 
97  if (fread(ca.grid, ca.stride, ca.height, input) !=
98  (unsigned int)ca.height) {
99  if (feof(input))
100  G_fatal_error(_("Cairo: error reading BMP file <%s>: "
101  "unexpected end of file"),
102  ca.file_name);
103  else if (ferror(input))
104  G_fatal_error(_("Cairo: error reading BMP file <%s>: %s"),
105  ca.file_name, strerror(errno));
106  }
107 
108  fclose(input);
109 }
void cairo_read_bmp(void)
GRASS cairo display driver - header file.
#define HEADER_SIZE
Definition: cairodriver.h:46
struct cairo_state ca
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
#define _(str)
Definition: glocale.h:10
unsigned char * grid
Definition: cairodriver.h:69
char * file_name
Definition: cairodriver.h:66