-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathreadbmp.cpp
155 lines (129 loc) · 4.6 KB
/
readbmp.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/*
* readBMP.c
*
* Created by Nina Amenta on Sun May 23 2004.
* Free to good home!
*
*/
#include <stdio.h> // Header file for standard file i/o.
#include <stdlib.h> // Header file for malloc/free.
#include "readBMP.h"
/* Simple BMP reading code, should be adaptable to many
systems. Originally from Windows, ported to Linux, now works on my Mac
OS system.
NOTE!! only reads 24-bit RGB, single plane, uncompressed, unencoded
BMP, not all BMPs. BMPs saved by xv should be fine. */
//
// This code was created by Jeff Molofee '99
// (www.demonews.com/hosted/nehe)
// Ported to Linux/GLUT by Richard Campbell '99
// Code and comments for adaptation to big endian/little endian systems
// Nina Amenta '04
//
/* Reads a long 32 bit integer; comment out one or the other shifting line below,
whichever makes your system work right. */
unsigned int endianReadInt(FILE* file) {
unsigned char b[4];
unsigned int i;
if (fread(b, 1, 4, file) < 4)
return 0;
/* LITTLE VS BIG ENDIAN LINES - comment out one or the other */
i = (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | b[0]; // big endian
//i = (b[0]<<24) | (b[1]<<16) | (b[2]<<8) | b[3]; // little endian
return i;
}
/* Reads a 16 bit integer; comment out one or the other shifting line below,
whichever makes your system work right. */
unsigned short int endianReadShort(FILE* file) {
unsigned char b[2];
unsigned short s;
if (fread(b, 1, 2, file) < 2)
return 0;
/* LITTLE VS BIG ENDIAN LINES - comment out one or the other */
s = (b[1] << 8) | b[0]; // big endian
//s = (b[0]<<8) | b[1]; // little endian
return s;
}
// quick and dirty bitmap loader...for 24 bit bitmaps with 1 plane only.
// See http://www.dcs.ed.ac.uk/~mxr/gfx/2d/BMP.txt for more info.
int ImageLoad(char *filename, Image *image) {
FILE *file;
unsigned long size; // size of the image in bytes.
unsigned long greysize; // size of the image in bytes.
unsigned long i; // standard counter.
unsigned short int planes; // number of planes in image (must be 1)
unsigned short int bpp; // number of bits per pixel (must be 24)
unsigned char temp; // temporary color storage for bgr-rgb conversion.
// make sure the file is there.
if ((file = fopen(filename, "rb")) == NULL)
{
printf("File Not Found : %s\n", filename);
return 0;
}
// seek through the bmp header, up to the width/height:
fseek(file, 18, SEEK_CUR);
// read the width
if (!(image->sizeX = endianReadInt(file))) {
printf("Error reading width from %s.\n", filename);
return 0;
}
//printf("Width of %s: %lu\n", filename, image->sizeX);
// read the height
if (!(image->sizeY = endianReadInt(file))) {
printf("Error reading height from %s.\n", filename);
return 0;
}
//printf("Height of %s: %lu\n", filename, image->sizeY);
// calculate the size (assuming 24 bits or 3 bytes per pixel).
size = image->sizeX * image->sizeY * 3;
greysize = image->sizeX * image->sizeY;
// read the planes
if (!(planes = endianReadShort(file))) {
printf("Error reading planes from %s.\n", filename);
return 0;
}
if (planes != 1) {
printf("Planes from %s is not 1: %u\n", filename, planes);
return 0;
}
// read the bits per pixel
if (!(bpp = endianReadShort(file))) {
printf("Error reading bpp from %s.\n", filename);
return 0;
}
if (bpp != 24) {
printf("Bpp from %s is not 24: %u\n", filename, bpp);
return 0;
}
// seek past the rest of the bitmap header.
fseek(file, 24, SEEK_CUR);
// read the data.
image->data = (unsigned char *)malloc(size);
if (image->data == NULL) {
printf("Error allocating memory for color-corrected image data");
return 0;
}
if ((i = fread(image->data, size, 1, file)) != 1) {
printf("Error reading image data from %s.\n", filename);
return 0;
}
for (i = 0; i<size; i += 3) { // reverse all of the colors. (bgr -> rgb)
//temp = image->data[i];
//image->data[i] = image->data[i + 2];
//image->data[i + 2] = temp;
temp = image->data[i];
image->data[i] = image->data[i + 2];
image->data[i + 2] = temp;
}
image->greydata = (unsigned char *)malloc(greysize);
if (image->greydata == NULL) {
printf("Error allocating memory for greyimage data");
return 0;
}
for (i = 0; i<greysize; i += 1) {
int temp = ((unsigned char(image->data[3 * i]) * 299 + unsigned char(image->data[3 * i + 1]) * 587 + unsigned char(image->data[3 * i + 2]) * 114 + 500)) / 1000;
image->greydata[i] = unsigned char(temp);
}
// we're done.
return 1;
}