| 296 | |
| 297 | |
| 298 | int bmp_save(char *filename, unsigned char *buf, int width, int pitch, |
| 299 | int height, int format, enum BMPORN orientation) |
| 300 | { |
| 301 | int fd = -1, bytesWritten, dstPitch, ret = 0; |
| 302 | int flags = O_RDWR | O_CREAT | O_TRUNC; |
| 303 | unsigned char *tempbuf = NULL; char *temp; |
| 304 | BitmapHeader bh; int mode; |
| 305 | PF *pf = pf_get(format); |
| 306 | |
| 307 | #ifdef _WIN32 |
| 308 | flags |= O_BINARY; mode = _S_IREAD | _S_IWRITE; |
| 309 | #else |
| 310 | mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; |
| 311 | #endif |
| 312 | if(!filename || !buf || width < 1 || height < 1 || pf->bpc < 8 || pitch < 0) |
| 313 | THROW("Invalid argument to bmp_save()"); |
| 314 | |
| 315 | if(pitch == 0) pitch = width * pf->size; |
| 316 | |
| 317 | if((temp = strrchr(filename, '.')) != NULL) |
| 318 | { |
| 319 | if(!stricmp(temp, ".ppm")) |
| 320 | return ppm_save(filename, buf, width, pitch, height, pf, orientation); |
| 321 | } |
| 322 | |
| 323 | TRY_UNIX(fd = open(filename, flags, mode)); |
| 324 | dstPitch = ((width * 3) + 3) & (~3); |
| 325 | |
| 326 | bh.bfType = 0x4d42; |
| 327 | bh.bfSize = BMPHDRSIZE + dstPitch * height; |
| 328 | bh.bfReserved1 = 0; bh.bfReserved2 = 0; |
| 329 | bh.bfOffBits = BMPHDRSIZE; |
| 330 | bh.biSize = 40; |
| 331 | bh.biWidth = width; bh.biHeight = height; |
| 332 | bh.biPlanes = 0; bh.biBitCount = 24; |
| 333 | bh.biCompression = BI_RGB; bh.biSizeImage = 0; |
| 334 | bh.biXPelsPerMeter = 0; bh.biYPelsPerMeter = 0; |
| 335 | bh.biClrUsed = 0; bh.biClrImportant = 0; |
| 336 | |
| 337 | if(!LittleEndian()) |
| 338 | { |
| 339 | bh.bfType = BYTESWAP16(bh.bfType); |
| 340 | bh.bfSize = BYTESWAP(bh.bfSize); |
| 341 | bh.bfOffBits = BYTESWAP(bh.bfOffBits); |
| 342 | bh.biSize = BYTESWAP(bh.biSize); |
| 343 | bh.biWidth = BYTESWAP(bh.biWidth); |
| 344 | bh.biHeight = BYTESWAP(bh.biHeight); |
| 345 | bh.biPlanes = BYTESWAP16(bh.biPlanes); |
| 346 | bh.biBitCount = BYTESWAP16(bh.biBitCount); |
| 347 | bh.biCompression = BYTESWAP(bh.biCompression); |
| 348 | bh.biSizeImage = BYTESWAP(bh.biSizeImage); |
| 349 | bh.biXPelsPerMeter = BYTESWAP(bh.biXPelsPerMeter); |
| 350 | bh.biYPelsPerMeter = BYTESWAP(bh.biYPelsPerMeter); |
| 351 | bh.biClrUsed = BYTESWAP(bh.biClrUsed); |
| 352 | bh.biClrImportant = BYTESWAP(bh.biClrImportant); |
| 353 | } |
| 354 | |
| 355 | WRITE(fd, &bh.bfType, sizeof(unsigned short)); |