mirror of
https://github.com/aseprite/aseprite.git
synced 2025-04-09 18:44:46 +00:00
Remove Allegro dependency from load/save_pic_file
This commit is contained in:
parent
ff49b50047
commit
d1bd775270
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user