/******************************************************************************* * bmp5.c * Microsoft Windows bitmap (BMP) file writing functions. * * 1.0 09-17-92 drt. Split off from bmp4.c. * * Copyright (c)1992-94, David R. Tribble. */ /* includes */ #include #include #include #include #include #include #include "bmp.h" /* debug macros */ #ifndef DEBUG #define DEBUG 0 #endif #if DEBUG-0 <= 0 #undef DEBUG #define DEBUG 0 #endif #if DEBUG #define D(expr) expr #else #define D(expr) 0 #endif /******************************************************************************* * bmp_write_eof * Writes end of file marker to BMP file `fp'. * * returns * Zero on success, otherwise -1. */ int bmp_write_eof(BMP_FILE *fp) { /* check args */ if (fp == NULL) { /* invalid pointer */ errno = EINVAL; return -1; } if (fp->fp == NULL) { /* file is not open */ errno = EBADF; return -1; } /* write end of file */ switch (fp->h.biCompression) { case BMP_CMP_RLE8: if (fp->rep != 0x00) { putc(fp->rep, fp->fp); putc(fp->pix, fp->fp); fp->rep = 0x00; fp->pix = 0x00; } putc(0x00, fp->fp); putc(0x01, fp->fp); break; #ifdef is_incomplete_ case BMP_CMP_RLE4: ... break; #endif case BMP_CMP_NONE: default: break; } return 0; } /******************************************************************************* * bmp_write_eoln * Writes end of pixel line marker to BMP file `fp'. * * returns * Zero on success, otherwise -1. */ int bmp_write_eoln(BMP_FILE *fp) { /* check args */ if (fp == NULL) { /* invalid pointer */ errno = EINVAL; return -1; } if (fp->fp == NULL) { /* file is not open */ errno = EBADF; return -1; } /* write end of line */ switch (fp->h.biCompression) { case BMP_CMP_RLE8: if (fp->rep != 0x00) { putc(fp->rep, fp->fp); putc(fp->pix, fp->fp); fp->byteno += 2; fp->rep = 0x00; fp->pix = 0x00; } break; #ifdef is_incomplete_ case BMP_CMP_RLE4: ... break; #endif case BMP_CMP_NONE: default: break; } while (fp->byteno < fp->linesz) { putc(0x00, fp->fp); fp->byteno++; } fp->byteno = 0; return 0; } /******************************************************************************* * bmp_write_rgb * Writes next RGB pixel value `pix' to BMP file `fp'. * * returns * Zero on success, or -1 on error or end of file. * This operation is only valid for 24-bit BMP files. */ int bmp_write_rgb(BMP_FILE *fp, struct bmp_rgbpix *pix) { /* check args */ if (fp == NULL) { /* invalid pointer */ errno = EINVAL; return -1; } if (fp->fp == NULL) { /* file is not open */ errno = EBADF; return -1; } if (fp->h.bits != 24) { /* file is not 24-bit */ return -1; } /* write 24-bit pixel value */ D(printf("write<%.2X:%.2X:%.2X>\n", pix->r, pix->g, pix->b)); if (putc(pix->b, fp->fp) == EOF) /* blue component */ return -1; fp->byteno++; if (putc(pix->g, fp->fp) == EOF) /* green component */ return -1; fp->byteno++; if (putc(pix->r, fp->fp) == EOF) /* red component */ return -1; fp->byteno++; return 0; } /******************************************************************************* * bmp_write_pixel * Writes next pixel value to BMP file `fp'. The pixel value should be in * the range [0x00,0xFF] for 1, 2, 4, and 8 bit colors, and in the range * [0x00000000,0x00FFFFFF] for 24-bit colors. * * returns * Zero on success, otherwise -1. */ int bmp_write_pixel(BMP_FILE *fp, long pix) { /* check args */ if (fp == NULL) { /* invalid pointer */ errno = EINVAL; return -1; } if (fp->fp == NULL) { /* file is not open */ errno = EBADF; return -1; } #ifdef New if (fp->byteno > ... ? fp->linesz) bmp_write_eoln(fp); #endif /* write next byte */ switch (fp->h.biCompression) { case BMP_CMP_RLE8: if (fp->rep != 0x00) { if (pix != fp->pix || fp->rep == 0xFF) { putc(fp->rep, fp->fp); /* repeat count */ putc(fp->pix, fp->fp); /* pixel value */ fp->byteno += 2; fp->rep = 0x00; } } fp->pix = pix; fp->rep++; break; #ifdef is_incomplete_ case BMP_CMP_RLE4: ... break; #endif case BMP_CMP_NONE: default: switch (fp->h.bits) { case 24: putc(pix & 0xFF, fp->fp); /* blue */ pix >>= 8; putc(pix & 0xFF, fp->fp); /* green */ pix >>= 8; putc(pix & 0xFF, fp->fp); /* red */ pix >>= 8; fp->byteno += 3; break; default: putc(pix, fp->fp); fp->byteno++; break; } break; } return 0; } /* end bmp4.c */