home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (C) 1996 by Raphael Quinet. All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby
- * granted, provided that the above copyright notice appear in all
- * copies and that both that copyright notice and this permission
- * notice appear in supporting documentation. If more than a few
- * lines of this code are used in a program which displays a copyright
- * notice or credit notice, the following acknowledgment must also be
- * displayed on the same screen: "This product includes software
- * developed by Raphael Quinet for use in the Quake Editing Utilities
- * project." THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR
- * IMPLIED WARRANTY.
- *
- * More information about the QEU project can be found on the WWW:
- * "http://www.montefiore.ulg.ac.be/~quinet/games/editing.html" or by
- * mail: Raphael Quinet, 9 rue des Martyrs, B-4550 Nandrin, Belgium.
- */
-
- /*
- * F_BITMAP.C - Filters for bitmap file formats.
- */
-
- #include "qeu.h"
- #include "q_misc.h"
- #include "q_files.h"
- #include "f_bitmap.h"
-
-
- /* ------------------------------------------------------------------------- */
- /* --- Routines for 256 colors palettes ------------------------------------ */
-
- /*
- * Read an RGB palette (256 * 3 bytes) from a file.
- */
- struct RGB *ReadPalette256(FILE *file, UInt32 offset)
- {
- struct RGB *palptr;
-
- if (file == NULL)
- return NULL;
- if (fseek(file, offset, SEEK_SET) < 0)
- return NULL;
- palptr = (struct RGB *)QMalloc(256L * (UInt32)sizeof(struct RGB));
- if (ReadBytes(file, palptr, 768L) == FALSE)
- {
- QFree(palptr);
- return NULL;
- }
- return palptr;
- }
-
-
- /*
- * Save an RGB palette (256 * 3 bytes) to a file.
- * Return the number of bytes written.
- */
- UInt32 SavePalette256(FILE *file, struct RGB *palette256)
- {
- if (file == NULL || WriteBytes(file, palette256, 768L) == FALSE)
- return 0L;
- return 768L;
- }
-
-
- /* ------------------------------------------------------------------------- */
- /* --- Routines for "flat" bitmaps ----------------------------------------- */
-
- /*
- * Create a new, empty bitmap.
- */
- BitMap *NewBitMap()
- {
- BitMap *bmptr;
-
- bmptr = (BitMap *)QMalloc((UInt32)sizeof(BitMap));
- bmptr->width = 0;
- bmptr->height = 0;
- bmptr->data = NULL;
- return bmptr;
- }
-
-
- /*
- * Discard a bitmap and free memory.
- */
- void FreeBitMap(BitMap *bmptr)
- {
- if (bmptr->data != NULL)
- QFree(bmptr->data);
- QFree(bmptr);
- }
-
-
- /*
- * Read a bitmap from a file (width + height + data).
- */
- BitMap *ReadBitMap(FILE *file, UInt32 offset)
- {
- BitMap *bmptr;
- UInt32 w, h;
-
- if (file == NULL)
- return NULL;
- bmptr = NewBitMap();
- if ((fseek(file, offset, SEEK_SET) < 0)
- || (ReadInt32(file, &w) == FALSE)
- || (w > 65535L)
- || (w == 0L)
- || (ReadInt32(file, &h) == FALSE)
- || (h > 65535L)
- || (h == 0L))
- {
- FreeBitMap(bmptr);
- return NULL;
- }
- bmptr->width = (UInt16)w;
- bmptr->height = (UInt16)h;
- bmptr->data = (UInt8 huge *)QMalloc(w * h);
- if (ReadBytes(file, bmptr->data, w * h) == FALSE)
- {
- FreeBitMap(bmptr);
- return NULL;
- }
- return bmptr;
- }
-
-
- /*
- * Read raw bitmap data from a file. The width and height must be
- * known in advance.
- */
- BitMap *ReadRawBitMap(FILE *file, UInt32 offset, UInt16 width, UInt16 height)
- {
- BitMap *bmptr;
-
- if (file == NULL)
- return NULL;
- bmptr = NewBitMap();
- if (fseek(file, offset, SEEK_SET) < 0)
- {
- FreeBitMap(bmptr);
- return NULL;
- }
- bmptr->width = width;
- bmptr->height = height;
- bmptr->data = (UInt8 huge *)QMalloc((UInt32)width * (UInt32)height);
- if (ReadBytes(file, bmptr->data, (UInt32)width * (UInt32)height) == FALSE)
- {
- FreeBitMap(bmptr);
- return NULL;
- }
- return bmptr;
- }
-
-
- /*
- * Save a bitmap to a file (width + height + data).
- * The number of bytes written is returned (0 if an error occured).
- */
- UInt32 SaveBitMap(FILE *file, BitMap *bmptr)
- {
- UInt32 w, h;
-
- if (file == NULL || bmptr->width == 0 || bmptr->height == 0)
- return 0L;
- w = (UInt32)(bmptr->width);
- h = (UInt32)(bmptr->height);
- if ((WriteInt32(file, &w) == FALSE)
- || (WriteInt32(file, &h) == FALSE)
- || (WriteBytes(file, bmptr->data, w * h) == FALSE))
- return 0L;
- return w * h + 8L;
- }
-
-
- /*
- * Save raw bitmap data to a file.
- * The number of bytes written is returned (0 if an error occured).
- */
- UInt32 SaveRawBitMap(FILE *file, BitMap *bmptr)
- {
- if (file == NULL || bmptr->width == 0 || bmptr->height == 0)
- return 0L;
- if (WriteBytes(file, bmptr->data,
- (UInt32)(bmptr->width) * (UInt32)(bmptr->height)) == FALSE)
- return 0L;
- return (UInt32)(bmptr->width) * (UInt32)(bmptr->height);
- }
-
-
- /*
- * Print the contents of a bitmap in "outf".
- */
- void DumpBitMap(FILE *outf, BitMap *bmptr)
- {
- UInt16 r, c;
- UInt8 huge *x;
-
- if (outf == NULL || bmptr == NULL)
- return;
- fprintf(outf, "Size = (%u * %u), %lu bytes.\n",
- bmptr->width, bmptr->height,
- (UInt32)(bmptr->width) * (UInt32)(bmptr->height));
- x = bmptr->data;
- for (r = 0; r < bmptr->height; r++)
- {
- for (c = 0; c < bmptr->width; c++)
- fprintf(outf, "%02x ", *x++);
- fprintf(outf, "\n");
- }
- }
-
- /* ------------------------------------------------------------------------- */
- /* --- Routines for PPM files (pbmplus) ------------------------------------ */
-
- /*
- * Save a bitmap as a PPM file (raw format, 24 bits per pixel). See
- * the pbmplus package for more information. PPM files can be read by
- * XV and other graphics programs and can be converted easily to other
- * formats.
- */
- UInt32 SavePPM(FILE *file, BitMap *bmptr, struct RGB *palette256)
- {
- char buf[20];
- UInt32 size;
- UInt16 r, c;
- UInt8 huge *x;
-
- if (file == NULL || bmptr->width == 0 || bmptr->height == 0
- || palette256 == NULL)
- return 0L;
- sprintf(buf, "P6\n%u %u\n255\n", bmptr->width, bmptr->height);
- size = (UInt32)strlen(buf);
- if (WriteBytes(file, buf, size) == FALSE)
- return 0L;
- x = bmptr->data;
- for (r = 0; r < bmptr->height; r++)
- for (c = 0; c < bmptr->width; c++)
- {
- if (WriteBytes(file, &(palette256[*x++]), 3) == FALSE)
- return 0L;
- size += 3L;
- }
- return size;
- }
-
-
- /* ------------------------------------------------------------------------- */
- /* --- Routines for BMP files (MS Windows) --------------------------------- */
-
- struct BMPHeader
- {
- /* BITMAPFILEHEADER */
- UInt32 bfSize; /* total size of file */
- UInt16 bfReserved1; /* always 0 */
- UInt16 bfReserved2; /* always 0 */
- Int32 bfOffBits; /* offset to start of bitmap data */
-
- /* BITMAPINFOHEADER */
- UInt32 biSize; /* size of bitmap header, always 40 here */
- Int32 biWidth; /* width of the bitmap, in pixels */
- Int32 biHeight; /* height of the bitmap, in pixels */
- UInt16 biPlanes; /* number of planes, always 1 */
- UInt16 biBitCount; /* number of bits per pixel, always 8 here */
- UInt32 biCompression; /* compression, always 0 here */
- UInt32 biSizeImage; /* size of the image */
- Int32 biXPelsPerMeter; /* horizontal resolution */
- Int32 biYPelsPerMeter; /* vertical resolution */
- UInt32 biClrUsed; /* number of colors used, always 256 here */
- UInt32 biClrImportant; /* number of "important" colors */
- };
-
-
- /*
- * Save a bitmap as a BMP file (no compression, 8 bits per pixel). This can
- * be read by most Windows programs. Note that this routine is simplified
- * and will only work for bitmaps with a 256 colors palette.
- */
- UInt32 SaveBMP(FILE *file, BitMap *bmptr, struct RGB *palette256)
- {
- struct BMPHeader bmphdr;
- UInt8 huge *x;
- UInt8 huge *buffer;
- Int16 r, c;
- UInt16 linesize;
- UInt32 imgsize;
- UInt32 imgoffset;
- int i;
-
- if (file == NULL || bmptr->width == 0 || bmptr->height == 0
- || palette256 == NULL)
- return 0L;
- linesize = (bmptr->width + 3) & (~3);
- imgsize = (UInt32)linesize * (UInt32)bmptr->height;
- imgoffset = 2L + (UInt32)sizeof(struct BMPHeader) + 1024L;
-
- /* write the BMP header */
- if (WriteBytes(file, "BM", 2L) == FALSE)
- return 0L;
- bmphdr.bfSize = SwapInt32(imgoffset + imgsize);
- bmphdr.bfReserved1 = 0;
- bmphdr.bfReserved2 = 0;
- bmphdr.bfOffBits = SwapInt32(imgoffset);
- bmphdr.biSize = SwapInt32(40L);
- bmphdr.biWidth = SwapInt32((UInt32)bmptr->width);
- bmphdr.biHeight = SwapInt32((UInt32)bmptr->height);
- bmphdr.biPlanes = SwapInt16(1);
- bmphdr.biBitCount = SwapInt16(8);
- bmphdr.biCompression = 0L;
- bmphdr.biSizeImage = SwapInt32(imgsize);
- bmphdr.biXPelsPerMeter = SwapInt32(1181L); /* 30 dpi - low res */
- bmphdr.biYPelsPerMeter = SwapInt32(1181L); /* 30 dpi - low res */
- bmphdr.biClrUsed = SwapInt32(256L);
- bmphdr.biClrImportant = 0L;
- if (WriteBytes(file, &bmphdr, sizeof(struct BMPHeader)) == FALSE)
- return 0L;
-
- if (linesize < 1024)
- buffer = (UInt8 huge *)QMalloc(1024L);
- else
- buffer = (UInt8 huge *)QMalloc((UInt32)linesize);
-
- /* write the color palette */
- x = buffer;
- for (i = 0; i < 256; i++)
- {
- *x++ = palette256[i].B;
- *x++ = palette256[i].G;
- *x++ = palette256[i].R;
- *x++ = 0;
- }
- if (WriteBytes(file, buffer, 1024L) == FALSE)
- {
- QFree(buffer);
- return 0L;
- }
-
- /* write the bitmap data (from bottom to top) */
- for (r = bmptr->height - 1; r >= 0; r--)
- {
- for (c = 0; c < bmptr->width; c++)
- buffer[c] = bmptr->data[c + bmptr->width * r];
- for(; c < linesize; c++)
- buffer[c] = 0;
- if (WriteBytes(file, buffer, (UInt32)linesize) == FALSE)
- {
- QFree(buffer);
- return 0L;
- }
- }
- QFree(buffer);
- return imgoffset + imgsize;
- }
-
- /* end of file */
-