| 171 | |
| 172 | |
| 173 | int bmp_load(char *filename, unsigned char **buf, int *width, int align, |
| 174 | int *height, int format, enum BMPORN orientation) |
| 175 | { |
| 176 | int fd = -1, bytesRead, srcPitch, srcPixelSize, dstPitch, ret = 0; |
| 177 | enum BMPORN srcOrientation = BMPORN_BOTTOMUP; |
| 178 | unsigned char *tempbuf = NULL; |
| 179 | BitmapHeader bh; int flags = O_RDONLY; |
| 180 | PF *pf = pf_get(format); |
| 181 | |
| 182 | #ifdef _WIN32 |
| 183 | flags |= O_BINARY; |
| 184 | #endif |
| 185 | if(!filename || !buf || !width || !height || pf->bpc < 8 || align < 1) |
| 186 | THROW("Invalid argument to bmp_load()"); |
| 187 | if((align & (align - 1)) != 0) |
| 188 | THROW("Alignment must be a power of 2"); |
| 189 | TRY_UNIX(fd = open(filename, flags)); |
| 190 | |
| 191 | READ(fd, &bh.bfType, sizeof(unsigned short)); |
| 192 | if(!LittleEndian()) bh.bfType = BYTESWAP16(bh.bfType); |
| 193 | |
| 194 | if(bh.bfType == 0x3650) |
| 195 | { |
| 196 | CATCH(ppm_load(&fd, buf, width, align, height, pf, orientation, 0)); |
| 197 | goto finally; |
| 198 | } |
| 199 | if(bh.bfType == 0x3350) |
| 200 | { |
| 201 | CATCH(ppm_load(&fd, buf, width, align, height, pf, orientation, 1)); |
| 202 | goto finally; |
| 203 | } |
| 204 | |
| 205 | READ(fd, &bh.bfSize, sizeof(unsigned int)); |
| 206 | READ(fd, &bh.bfReserved1, sizeof(unsigned short)); |
| 207 | READ(fd, &bh.bfReserved2, sizeof(unsigned short)); |
| 208 | READ(fd, &bh.bfOffBits, sizeof(unsigned int)); |
| 209 | READ(fd, &bh.biSize, sizeof(unsigned int)); |
| 210 | READ(fd, &bh.biWidth, sizeof(int)); |
| 211 | READ(fd, &bh.biHeight, sizeof(int)); |
| 212 | READ(fd, &bh.biPlanes, sizeof(unsigned short)); |
| 213 | READ(fd, &bh.biBitCount, sizeof(unsigned short)); |
| 214 | READ(fd, &bh.biCompression, sizeof(unsigned int)); |
| 215 | READ(fd, &bh.biSizeImage, sizeof(unsigned int)); |
| 216 | READ(fd, &bh.biXPelsPerMeter, sizeof(int)); |
| 217 | READ(fd, &bh.biYPelsPerMeter, sizeof(int)); |
| 218 | READ(fd, &bh.biClrUsed, sizeof(unsigned int)); |
| 219 | READ(fd, &bh.biClrImportant, sizeof(unsigned int)); |
| 220 | |
| 221 | if(!LittleEndian()) |
| 222 | { |
| 223 | bh.bfSize = BYTESWAP(bh.bfSize); |
| 224 | bh.bfOffBits = BYTESWAP(bh.bfOffBits); |
| 225 | bh.biSize = BYTESWAP(bh.biSize); |
| 226 | bh.biWidth = BYTESWAP(bh.biWidth); |
| 227 | bh.biHeight = BYTESWAP(bh.biHeight); |
| 228 | bh.biPlanes = BYTESWAP16(bh.biPlanes); |
| 229 | bh.biBitCount = BYTESWAP16(bh.biBitCount); |
| 230 | bh.biCompression = BYTESWAP(bh.biCompression); |