Remove Allegro dependency from load/save_pic_file

This commit is contained in:
David Capello 2014-09-21 00:36:20 -03:00
parent ff49b50047
commit d1bd775270
2 changed files with 103 additions and 115 deletions

View File

@ -20,26 +20,28 @@
#include "config.h" #include "config.h"
#endif #endif
#include "base/cfile.h"
#include "base/file_handle.h"
#include "base/unique_ptr.h" #include "base/unique_ptr.h"
#include "raster/color_scales.h"
#include "raster/image.h" #include "raster/image.h"
#include "raster/palette.h"
#include "raster/primitives.h" #include "raster/primitives.h"
#include <allegro/color.h> #include <cstdio>
#include <allegro/file.h>
namespace app { namespace app {
using namespace raster; using namespace raster;
// Loads a PIC file (Animator and Animator Pro format) // Loads a PIC file (Animator and Animator Pro format)
Image* load_pic_file(const char* filename, int* x, int* y, RGB* palette) Image* load_pic_file(const char* filename, int* x, int* y, Palette** palette)
{ {
base::UniquePtr<Image> image; base::UniquePtr<Image> image;
int size, compression; int size, compression;
int image_size; int image_size;
int block_size; int block_size;
int block_type; int block_type;
PACKFILE *f;
int version; int version;
int r, g, b; int r, g, b;
int c, u, v; int c, u, v;
@ -48,38 +50,38 @@ Image* load_pic_file(const char* filename, int* x, int* y, RGB* palette)
int byte; int byte;
int bpp; int bpp;
f = pack_fopen (filename, F_READ); base::FileHandle f(base::open_file_with_exception(filename, "rb"));
if (!f)
return NULL;
/* Animator format? */ // Animator format?
magic = pack_igetw (f); magic = base::fgetw(f);
if (magic == 0x9119) { if (magic == 0x9119) {
/* read Animator PIC file ***************************************/ // Read Animator PIC file
w = pack_igetw (f); /* width */ w = base::fgetw(f); // width
h = pack_igetw (f); /* height */ h = base::fgetw(f); // height
*x = ((short)pack_igetw (f)); /* X offset */ *x = ((short)base::fgetw(f)); // X offset
*y = ((short)pack_igetw (f)); /* Y offset */ *y = ((short)base::fgetw(f)); // Y offset
bpp = pack_getc (f); /* bits per pixel (must be 8) */ bpp = std::fgetc(f); // bits per pixel (must be 8)
compression = pack_getc (f); /* compression flag (must be 0) */ compression = std::fgetc(f); // compression flag (must be 0)
image_size = pack_igetl (f); /* image size (in bytes) */ image_size = base::fgetl(f); // image size (in bytes)
pack_getc (f); /* reserved */ std::fgetc(f); // reserved
if (bpp != 8 || compression != 0) { if (bpp != 8 || compression != 0) {
pack_fclose (f);
return NULL; return NULL;
} }
/* read palette (RGB in 0-63) */ // Read palette (RGB in 0-63)
if (palette) {
*palette = new Palette(FrameNumber(0), Palette::MaxColors);
}
for (c=0; c<256; c++) { for (c=0; c<256; c++) {
r = pack_getc (f); r = std::fgetc(f);
g = pack_getc (f); g = std::fgetc(f);
b = pack_getc (f); b = std::fgetc(f);
if (palette) { if (palette)
palette[c].r = r; (*palette)->setEntry(c, rgba(
palette[c].g = g; scale_6bits_to_8bits(r),
palette[c].b = b; scale_6bits_to_8bits(g),
} scale_6bits_to_8bits(b), 255));
} }
// Read image // Read image
@ -87,85 +89,74 @@ Image* load_pic_file(const char* filename, int* x, int* y, RGB* palette)
for (v=0; v<h; v++) for (v=0; v<h; v++)
for (u=0; u<w; u++) for (u=0; u<w; u++)
image->putPixel(u, v, pack_getc(f)); image->putPixel(u, v, std::fgetc(f));
pack_fclose(f);
return image.release(); return image.release();
} }
/* rewind */ // rewind
pack_fclose (f); f.reset(NULL);
f = pack_fopen (filename, F_READ); f = base::open_file_with_exception(filename, "rb");
if (!f)
// read a PIC/MSK Animator Pro file
size = base::fgetl(f); // file size
magic = base::fgetw(f); // magic number 9500h
if (magic != 0x9500)
return NULL; return NULL;
/* read a PIC/MSK Animator Pro file *************************************/ w = base::fgetw(f); // width
size = pack_igetl (f); /* file size */ h = base::fgetw(f); // height
magic = pack_igetw (f); /* magic number 9500h */ *x = base::fgetw(f); // X offset
if (magic != 0x9500) { *y = base::fgetw(f); // Y offset
pack_fclose (f); base::fgetl(f); // user ID, is 0
bpp = std::fgetc(f); // bits per pixel
if ((bpp != 1 && bpp != 8) || (w<1) || (h<1) || (w>9999) || (h>9999))
return NULL; return NULL;
}
w = pack_igetw (f); /* width */ // Skip reserved data
h = pack_igetw (f); /* height */
*x = pack_igetw (f); /* X offset */
*y = pack_igetw (f); /* Y offset */
pack_igetl (f); /* user ID, is 0 */
bpp = pack_getc (f); /* bits per pixel */
if ((bpp != 1 && bpp != 8) || (w<1) || (h<1) || (w>9999) || (h>9999)) {
pack_fclose (f);
return NULL;
}
/* skip reserved data */
for (c=0; c<45; c++) for (c=0; c<45; c++)
pack_getc (f); std::fgetc(f);
size -= 64; /* the header uses 64 bytes */ size -= 64; // The header uses 64 bytes
image.reset(Image::create(bpp == 8 ? IMAGE_INDEXED: IMAGE_BITMAP, w, h)); image.reset(Image::create(bpp == 8 ? IMAGE_INDEXED: IMAGE_BITMAP, w, h));
/* read blocks to end of file */ /* read blocks to end of file */
while (size > 0) { while (size > 0) {
block_size = pack_igetl (f); block_size = base::fgetl(f);
block_type = pack_igetw (f); block_type = base::fgetw(f);
switch (block_type) { switch (block_type) {
/* color palette info */ // Color palette info
case 0: case 0:
version = pack_igetw (f); /* palette version */ version = base::fgetw(f); // Palette version
if (version != 0) { if (version != 0)
pack_fclose (f);
return NULL; return NULL;
}
/* 256 RGB entries in 0-255 format */ // 256 RGB entries in 0-255 format
for (c=0; c<256; c++) { for (c=0; c<256; c++) {
r = pack_getc (f); r = std::fgetc(f);
g = pack_getc (f); g = std::fgetc(f);
b = pack_getc (f); b = std::fgetc(f);
if (palette) { if (palette)
palette[c].r = MID (0, r, 255) >> 2; (*palette)->setEntry(c, rgba(r, g, b, 255));
palette[c].g = MID (0, g, 255) >> 2;
palette[c].b = MID (0, b, 255) >> 2;
}
} }
break; break;
/* byte-per-pixel image data */ // Byte-per-pixel image data
case 1: case 1:
for (v=0; v<h; v++) for (v=0; v<h; v++)
for (u=0; u<w; u++) for (u=0; u<w; u++)
image->putPixel(u, v, pack_getc(f)); image->putPixel(u, v, std::fgetc(f));
break; break;
/* bit-per-pixel image data */ // Bit-per-pixel image data
case 2: case 2:
for (v=0; v<h; v++) for (v=0; v<h; v++)
for (u=0; u<(w+7)/8; u++) { for (u=0; u<(w+7)/8; u++) {
byte = pack_getc (f); byte = std::fgetc(f);
for (c=0; c<8; c++) for (c=0; c<8; c++)
put_pixel(image, u*8+c, v, byte & (1<<(7-c))); put_pixel(image, u*8+c, v, byte & (1<<(7-c)));
} }
@ -175,15 +166,13 @@ Image* load_pic_file(const char* filename, int* x, int* y, RGB* palette)
size -= block_size; size -= block_size;
} }
pack_fclose (f);
return image.release(); return image.release();
} }
// Saves an Animator Pro PIC file // Saves an Animator Pro PIC file
int save_pic_file(const char *filename, int x, int y, const RGB* palette, const Image* image) int save_pic_file(const char *filename, int x, int y, const Palette* palette, const Image* image)
{ {
int c, u, v, bpp, size, byte; int c, u, v, bpp, size, byte;
PACKFILE* f;
if (image->pixelFormat() == IMAGE_INDEXED) if (image->pixelFormat() == IMAGE_INDEXED)
bpp = 8; bpp = 8;
@ -195,66 +184,66 @@ int save_pic_file(const char *filename, int x, int y, const RGB* palette, const
if ((bpp == 8) && (!palette)) if ((bpp == 8) && (!palette))
return -1; return -1;
f = pack_fopen (filename, F_WRITE); base::FileHandle f(base::open_file_with_exception(filename, "wb"));
if (!f)
return -1;
size = 64; size = 64;
/* bit-per-pixel image data block */ // Bit-per-pixel image data block
if (bpp == 1) if (bpp == 1)
size += (4+2+((image->width()+7)/8)*image->height()); size += (4+2+((image->width()+7)/8)*image->height());
/* color palette info + byte-per-pixel image data block */ // Color palette info + byte-per-pixel image data block
else else
size += (4+2+2+256*3) + (4+2+image->width()*image->height()); size += (4+2+2+256*3) + (4+2+image->width()*image->height());
pack_iputl(size, f); /* file size */ base::fputl(size, f); /* file size */
pack_iputw(0x9500, f); /* magic number 9500h */ base::fputw(0x9500, f); /* magic number 9500h */
pack_iputw(image->width(), f); /* width */ base::fputw(image->width(), f); /* width */
pack_iputw(image->height(), f); /* height */ base::fputw(image->height(), f); /* height */
pack_iputw(x, f); /* X offset */ base::fputw(x, f); /* X offset */
pack_iputw(y, f); /* Y offset */ base::fputw(y, f); /* Y offset */
pack_iputl(0, f); /* user ID, is 0 */ base::fputl(0, f); /* user ID, is 0 */
pack_putc(bpp, f); /* bits per pixel */ std::fputc(bpp, f); /* bits per pixel */
/* reserved data */ // Reserved data
for (c=0; c<45; c++) for (c=0; c<45; c++)
pack_putc(0, f); std::fputc(0, f);
/* 1 bpp */ // 1 bpp
if (bpp == 1) { if (bpp == 1) {
/* bit-per-data image data block */ // Bit-per-data image data block
pack_iputl((4+2+((image->width()+7)/8)*image->height()), f); /* block size */ base::fputl((4+2+((image->width()+7)/8)*image->height()), f); // Block size
pack_iputw(2, f); /* block type */ base::fputw(2, f); // Block type
for (v=0; v<image->height(); v++) /* image data */ for (v=0; v<image->height(); v++) // Image data
for (u=0; u<(image->width()+7)/8; u++) { for (u=0; u<(image->width()+7)/8; u++) {
byte = 0; byte = 0;
for (c=0; c<8; c++) for (c=0; c<8; c++)
if (get_pixel(image, u*8+c, v)) if (get_pixel(image, u*8+c, v))
byte |= (1<<(7-c)); byte |= (1<<(7-c));
pack_putc (byte, f); std::fputc(byte, f);
} }
} }
// 8 bpp // 8 bpp
else { else {
ASSERT(palette);
// Color palette info // Color palette info
pack_iputl((4+2+2+256*3), f); // Block size base::fputl((4+2+2+256*3), f); // Block size
pack_iputw(0, f); // Block type base::fputw(0, f); // Block type
pack_iputw(0, f); // Version base::fputw(0, f); // Version
for (c=0; c<256; c++) { // 256 palette entries for (c=0; c<256; c++) { // 256 palette entries
pack_putc(_rgb_scale_6[palette[c].r], f); color_t color = palette->getEntry(c);
pack_putc(_rgb_scale_6[palette[c].g], f); std::fputc(rgba_getr(color), f);
pack_putc(_rgb_scale_6[palette[c].b], f); std::fputc(rgba_getg(color), f);
std::fputc(rgba_getb(color), f);
} }
/* pixel-per-data image data block */ // Pixel-per-data image data block
pack_iputl ((4+2+image->width()*image->height()), f); // Block size base::fputl((4+2+image->width()*image->height()), f); // Block size
pack_iputw (1, f); // Block type base::fputw(1, f); // Block type
for (v=0; v<image->height(); v++) // Image data for (v=0; v<image->height(); v++) // Image data
for (u=0; u<image->width(); u++) for (u=0; u<image->width(); u++)
pack_putc(image->getPixel(u, v), f); std::fputc(image->getPixel(u, v), f);
} }
pack_fclose (f);
return 0; return 0;
} }

View File

@ -20,16 +20,15 @@
#define APP_UTIL_PIC_FILE_H_INCLUDED #define APP_UTIL_PIC_FILE_H_INCLUDED
#pragma once #pragma once
#include <allegro/color.h>
namespace raster { namespace raster {
class Image; class Image;
class Palette;
} }
namespace app { namespace app {
raster::Image* load_pic_file(const char* filename, int *x, int *y, RGB* palette); raster::Image* load_pic_file(const char* filename, int *x, int *y, raster::Palette** palette);
int save_pic_file(const char* filename, int x, int y, const RGB* palette, const raster::Image* image); int save_pic_file(const char* filename, int x, int y, const raster::Palette* palette, const raster::Image* image);
} // namespace app } // namespace app