Convert FileFormat to a C++ class.

This commit is contained in:
David Capello 2011-01-16 17:27:18 -03:00
parent 28ba73c168
commit 9fa71e5299
21 changed files with 597 additions and 399 deletions

View File

@ -176,9 +176,10 @@ add_library(aseprite-library
file/ase_format.cpp
file/bmp_format.cpp
file/file.cpp
file/file_format.cpp
file/file_formats_manager.cpp
file/fli/fli.cpp
file/fli_format.cpp
file/format_options.cpp
file/gif/format.cpp
file/gif/lzw.cpp
file/gif_format.cpp

View File

@ -39,6 +39,7 @@
#include "core/file_system.h"
#include "core/modules.h"
#include "file/file.h"
#include "file/file_formats_manager.h"
#include "gui/jinete.h"
#include "gui/jintern.h"
#include "log.h"
@ -130,6 +131,9 @@ App::App(int argc, char* argv[])
m_isGui = !(m_checkArgs->isConsoleOnly());
m_legacy = new LegacyModules(isGui() ? REQUIRE_INTERFACE: 0);
// Register well-known image file types.
FileFormatsManager::instance().registerAllFormats();
// init editor cursor
Editor::editor_cursor_init();

View File

@ -24,6 +24,7 @@
#include "zlib.h"
#include "file/file.h"
#include "file/file_format.h"
#include "raster/raster.h"
#define ASE_FILE_MAGIC 0xA5E0
@ -71,9 +72,6 @@ static ASE_FrameHeader *current_frame_header = NULL;
static int chunk_type;
static int chunk_start;
static bool load_ASE(FileOp *fop);
static bool save_ASE(FileOp *fop);
static bool ase_file_read_header(FILE* f, ASE_Header* header);
static void ase_file_prepare_header(FILE* f, ASE_Header* header, const Sprite* sprite);
static void ase_file_write_header(FILE* f, ASE_Header* header);
@ -103,26 +101,36 @@ static void ase_file_write_cel_chunk(FILE *f, Cel *cel, LayerImage *layer, Sprit
static Mask *ase_file_read_mask_chunk(FILE *f);
static void ase_file_write_mask_chunk(FILE *f, Mask *mask);
FileFormat format_ase =
class AseFormat : public FileFormat
{
"ase,aseprite",
"ase,aseprite",
load_ASE,
save_ASE,
NULL,
FILE_SUPPORT_RGB |
FILE_SUPPORT_RGBA |
FILE_SUPPORT_GRAY |
FILE_SUPPORT_GRAYA |
FILE_SUPPORT_INDEXED |
FILE_SUPPORT_LAYERS |
FILE_SUPPORT_FRAMES |
FILE_SUPPORT_PALETTES |
FILE_SUPPORT_MASKS_REPOSITORY |
FILE_SUPPORT_PATHS_REPOSITORY
const char* onGetName() const { return "ase"; }
const char* onGetExtensions() const { return "ase,aseprite"; }
int onGetFlags() const {
return
FILE_SUPPORT_LOAD |
FILE_SUPPORT_SAVE |
FILE_SUPPORT_RGB |
FILE_SUPPORT_RGBA |
FILE_SUPPORT_GRAY |
FILE_SUPPORT_GRAYA |
FILE_SUPPORT_INDEXED |
FILE_SUPPORT_LAYERS |
FILE_SUPPORT_FRAMES |
FILE_SUPPORT_PALETTES |
FILE_SUPPORT_MASKS_REPOSITORY |
FILE_SUPPORT_PATHS_REPOSITORY;
}
bool onLoad(FileOp* fop);
bool onSave(FileOp* fop);
};
static bool load_ASE(FileOp *fop)
FileFormat* CreateAseFormat()
{
return new AseFormat;
}
bool AseFormat::onLoad(FileOp *fop)
{
Sprite *sprite = NULL;
ASE_Header header;
@ -282,7 +290,7 @@ static bool load_ASE(FileOp *fop)
}
}
static bool save_ASE(FileOp *fop)
bool AseFormat::onSave(FileOp *fop)
{
Sprite *sprite = fop->sprite;
ASE_Header header;

View File

@ -23,25 +23,54 @@
#include <allegro/color.h>
#include "file/file.h"
#include "file/file_format.h"
#include "file/format_options.h"
#include "raster/raster.h"
static bool load_BMP(FileOp *fop);
static bool save_BMP(FileOp *fop);
FileFormat format_bmp =
class BmpFormat : public FileFormat
{
"bmp",
"bmp",
load_BMP,
save_BMP,
NULL,
FILE_SUPPORT_RGB |
FILE_SUPPORT_GRAY |
FILE_SUPPORT_INDEXED |
FILE_SUPPORT_SEQUENCES
enum {
BMP_OPTIONS_FORMAT_WINDOWS = 12,
BMP_OPTIONS_FORMAT_OS2 = 40,
BMP_OPTIONS_COMPRESSION_RGB = 0,
BMP_OPTIONS_COMPRESSION_RLE8 = 1,
BMP_OPTIONS_COMPRESSION_RLE4 = 2,
BMP_OPTIONS_COMPRESSION_BITFIELDS = 3
};
// Data for BMP files
class BmpOptions : public FormatOptions
{
public:
int format; /* BMP format */
int compression; /* BMP compression */
int bits_per_pixel; /* bits per pixel */
ase_uint32 red_mask; /* mask for red channel */
ase_uint32 green_mask; /* mask for green channel */
ase_uint32 blue_mask; /* mask for blue channel */
};
const char* onGetName() const { return "bmp"; }
const char* onGetExtensions() const { return "bmp"; }
int onGetFlags() const {
return
FILE_SUPPORT_LOAD |
FILE_SUPPORT_SAVE |
FILE_SUPPORT_RGB |
FILE_SUPPORT_GRAY |
FILE_SUPPORT_INDEXED |
FILE_SUPPORT_SEQUENCES;
}
bool onLoad(FileOp* fop);
bool onSave(FileOp* fop);
};
FileFormat* CreateBmpFormat()
{
return new BmpFormat;
}
#define BI_RGB 0
#define BI_RLE8 1
#define BI_RLE4 2
@ -567,7 +596,7 @@ static int read_bitfields_image(FILE *f, Image *image, BITMAPINFOHEADER *infohea
return 0;
}
static bool load_BMP(FileOp *fop)
bool BmpFormat::onLoad(FileOp *fop)
{
unsigned long rmask, gmask, bmask;
BITMAPFILEHEADER fileheader;
@ -680,7 +709,7 @@ static bool load_BMP(FileOp *fop)
/* setup the file-data */
if (fop->seq.format_options == NULL) {
BmpOptions *bmp_options = bmp_options_new();
BmpOptions* bmp_options = new BmpOptions();
bmp_options->format = format;
bmp_options->compression = infoheader.biCompression;
@ -689,14 +718,14 @@ static bool load_BMP(FileOp *fop)
bmp_options->green_mask = gmask;
bmp_options->blue_mask = bmask;
fop_sequence_set_format_options(fop, (FormatOptions *)bmp_options);
fop_sequence_set_format_options(fop, bmp_options);
}
fclose(f);
return true;
}
static bool save_BMP(FileOp *fop)
bool BmpFormat::onSave(FileOp *fop)
{
Image *image = fop->seq.image;
FILE *f;

View File

@ -26,6 +26,8 @@
#include "base/scoped_lock.h"
#include "console.h"
#include "file/file.h"
#include "file/file_format.h"
#include "file/file_formats_manager.h"
#include "file/format_options.h"
#include "gui/jalert.h"
#include "modules/gui.h"
@ -34,30 +36,6 @@
#include "raster/quantization.h"
#include "widgets/statebar.h"
extern FileFormat format_ase;
extern FileFormat format_bmp;
extern FileFormat format_fli;
extern FileFormat format_jpeg;
extern FileFormat format_pcx;
extern FileFormat format_tga;
extern FileFormat format_gif;
extern FileFormat format_ico;
extern FileFormat format_png;
static FileFormat *formats[] =
{
&format_ase,
&format_bmp,
&format_fli,
&format_jpeg,
&format_pcx,
&format_tga,
&format_gif,
&format_ico,
&format_png,
NULL
};
static FileOp *fop_new(FileOpType type);
static void fop_prepare_for_sequence(FileOp *fop);
@ -66,35 +44,37 @@ static int split_filename(const char *filename, char *left, char *right, int *wi
void get_readable_extensions(char* buf, int size)
{
int c;
FileFormatsList::iterator it = FileFormatsManager::instance().begin();
FileFormatsList::iterator end = FileFormatsManager::instance().end();
/* clear the string */
ustrncpy(buf, empty_string, size);
/* insert file format */
for (c=0; formats[c]; c++) {
if (formats[c]->load)
ustrncat(buf, formats[c]->exts, size);
if (formats[c+1] && formats[c]->load)
ustrncat(buf, ",", size);
for (; it != end; ++it) {
if ((*it)->support(FILE_SUPPORT_LOAD)) {
if (ustrcmp(buf, empty_string) != 0)
ustrncat(buf, ",", size);
ustrncat(buf, (*it)->extensions(), size);
}
}
}
void get_writable_extensions(char* buf, int size)
{
int c;
FileFormatsList::iterator it = FileFormatsManager::instance().begin();
FileFormatsList::iterator end = FileFormatsManager::instance().end();
/* clear the string */
ustrncpy(buf, empty_string, size);
/* insert file format */
for (c=0; formats[c]; c++) {
if (formats[c]->save)
ustrncat(buf, formats[c]->exts, size);
if (formats[c+1] && formats[c]->save)
ustrncat(buf, ",", size);
for (; it != end; ++it) {
if ((*it)->support(FILE_SUPPORT_SAVE)) {
if (ustrcmp(buf, empty_string) != 0)
ustrncat(buf, ",", size);
ustrncat(buf, (*it)->extensions(), size);
}
}
}
@ -167,13 +147,13 @@ FileOp *fop_to_load_sprite(const char *filename, int flags)
/* get the format through the extension of the filename */
fop->format = get_fileformat(extension);
if (!fop->format ||
!fop->format->load) {
!fop->format->support(FILE_SUPPORT_LOAD)) {
fop_error(fop, "ASE can't load \"%s\" files\n", extension);
goto done;
}
/* use the "sequence" interface */
if (fop->format->flags & FILE_SUPPORT_SEQUENCES) {
if (fop->format->support(FILE_SUPPORT_SEQUENCES)) {
/* prepare to load a sequence */
fop_prepare_for_sequence(fop);
@ -261,7 +241,7 @@ FileOp *fop_to_save_sprite(Sprite *sprite)
/* get the format through the extension of the filename */
fop->format = get_fileformat(extension);
if (!fop->format ||
!fop->format->save) {
!fop->format->support(FILE_SUPPORT_SAVE)) {
fop_error(fop, "ASE can't save \"%s\" files\n", extension);
return fop;
}
@ -274,29 +254,29 @@ FileOp *fop_to_save_sprite(Sprite *sprite)
switch (fop->sprite->getImgType()) {
case IMAGE_RGB:
if (!(fop->format->flags & FILE_SUPPORT_RGB)) {
if (!(fop->format->support(FILE_SUPPORT_RGB))) {
usprintf(buf+ustrlen(buf), "<<- %s", "RGB format");
fatal = true;
}
if (!(fop->format->flags & FILE_SUPPORT_RGBA) &&
if (!(fop->format->support(FILE_SUPPORT_RGBA)) &&
fop->sprite->needAlpha()) {
usprintf(buf+ustrlen(buf), "<<- %s", "Alpha channel");
}
break;
case IMAGE_GRAYSCALE:
if (!(fop->format->flags & FILE_SUPPORT_GRAY)) {
if (!(fop->format->support(FILE_SUPPORT_GRAY))) {
usprintf(buf+ustrlen(buf), "<<- Grayscale format");
fatal = true;
}
if (!(fop->format->flags & FILE_SUPPORT_GRAYA) &&
if (!(fop->format->support(FILE_SUPPORT_GRAYA)) &&
fop->sprite->needAlpha()) {
usprintf(buf+ustrlen(buf), "<<- Alpha channel");
}
break;
case IMAGE_INDEXED:
if (!(fop->format->flags & FILE_SUPPORT_INDEXED)) {
if (!(fop->format->support(FILE_SUPPORT_INDEXED))) {
usprintf(buf+ustrlen(buf), "<<- Indexed format");
fatal = true;
}
@ -304,28 +284,29 @@ FileOp *fop_to_save_sprite(Sprite *sprite)
}
// check frames support
if (!(fop->format->flags & (FILE_SUPPORT_FRAMES |
FILE_SUPPORT_SEQUENCES))) {
if (fop->sprite->getTotalFrames() > 1)
if (fop->sprite->getTotalFrames() > 1) {
if (!fop->format->support(FILE_SUPPORT_FRAMES) &&
!fop->format->support(FILE_SUPPORT_SEQUENCES)) {
usprintf(buf+ustrlen(buf), "<<- Frames");
}
}
// layers support
if (fop->sprite->getFolder()->get_layers_count() > 1) {
if (!(fop->format->flags & FILE_SUPPORT_LAYERS)) {
if (!(fop->format->support(FILE_SUPPORT_LAYERS))) {
usprintf(buf+ustrlen(buf), "<<- Layers");
}
}
// Palettes support.
if (fop->sprite->getPalettes().size() > 1) {
if (!(fop->format->flags & (FILE_SUPPORT_PALETTES |
FILE_SUPPORT_SEQUENCES))) {
if (!fop->format->support(FILE_SUPPORT_PALETTES) &&
!fop->format->support(FILE_SUPPORT_SEQUENCES)) {
usprintf(buf+ustrlen(buf), "<<- Palette changes between frames");
}
}
/* repositories */
// Repositories.
MasksList masks = fop->sprite->getMasksRepository();
if (!masks.empty()) {
int count = 0;
@ -340,13 +321,13 @@ FileOp *fop_to_save_sprite(Sprite *sprite)
count++;
}
if ((count > 0) && !(fop->format->flags & FILE_SUPPORT_MASKS_REPOSITORY)) {
if ((count > 0) && !(fop->format->support(FILE_SUPPORT_MASKS_REPOSITORY))) {
usprintf(buf+ustrlen(buf), "<<- Mask Repository");
}
}
if (!fop->sprite->getPathsRepository().empty()) {
if (!(fop->format->flags & FILE_SUPPORT_PATHS_REPOSITORY)) {
if (!(fop->format->support(FILE_SUPPORT_PATHS_REPOSITORY))) {
usprintf(buf+ustrlen(buf), "<<- Path Repository");
}
}
@ -360,12 +341,12 @@ FileOp *fop_to_save_sprite(Sprite *sprite)
if (fatal)
ret = jalert("Error<<File format \"%s\" doesn't support:%s"
"||&Close",
fop->format->name, buf);
fop->format->name(), buf);
else
ret = jalert("Warning<<File format \"%s\" doesn't support:%s"
"<<Do you want continue?"
"||&Yes||&No",
fop->format->name, buf);
fop->format->name(), buf);
/* operation can't be done (by fatal error) or the user cancel
the operation */
@ -381,8 +362,8 @@ FileOp *fop_to_save_sprite(Sprite *sprite)
}
}
/* use the "sequence" interface */
if (fop->format->flags & FILE_SUPPORT_SEQUENCES) {
// Use the "sequence" interface.
if (fop->format->support(FILE_SUPPORT_SEQUENCES)) {
fop_prepare_for_sequence(fop);
/* to save one frame */
@ -414,10 +395,10 @@ FileOp *fop_to_save_sprite(Sprite *sprite)
fop->filename = fop->sprite->getFilename();
/* configure output format? */
if (fop->format->get_options != NULL) {
FormatOptions *format_options = (fop->format->get_options)(fop);
if (fop->format->support(FILE_SUPPORT_GET_FORMAT_OPTIONS)) {
FormatOptions* format_options = fop->format->getFormatOptions(fop);
/* does the user cancelled the operation? */
// Does the user cancelled the operation?
if (format_options == NULL) {
fop_free(fop);
return NULL;
@ -446,7 +427,7 @@ void fop_operate(FileOp *fop)
/* load ***********************************************************/
if (fop->type == FileOpLoad &&
fop->format != NULL &&
fop->format->load != NULL) {
fop->format->support(FILE_SUPPORT_LOAD)) {
/* load a sequence */
if (fop->is_sequence()) {
int frame, frames, image_index = 0;
@ -490,7 +471,7 @@ void fop_operate(FileOp *fop)
fop->filename = it->c_str();
/* call the "load" procedure to read the first bitmap */
loadres = (*fop->format->load)(fop);
loadres = fop->format->load(fop);
if (!loadres) {
fop_error(fop, "Error loading frame %d from file \"%s\"\n",
frame+1, fop->filename.c_str());
@ -566,7 +547,7 @@ void fop_operate(FileOp *fop)
/* direct load from one file */
else {
/* call the "load" procedure */
if (!(*fop->format->load)(fop))
if (!fop->format->load(fop))
fop_error(fop, "Error loading sprite from file \"%s\"\n",
fop->filename.c_str());
}
@ -600,10 +581,10 @@ void fop_operate(FileOp *fop)
/* save ***********************************************************/
else if (fop->type == FileOpSave &&
fop->format != NULL &&
fop->format->save != NULL) {
fop->format->support(FILE_SUPPORT_SAVE)) {
/* save a sequence */
if (fop->is_sequence()) {
ASSERT(fop->format->flags & FILE_SUPPORT_SEQUENCES);
ASSERT(fop->format->support(FILE_SUPPORT_SEQUENCES));
/* create a temporary bitmap */
fop->seq.image = image_new(fop->sprite->getImgType(),
@ -631,7 +612,7 @@ void fop_operate(FileOp *fop)
fop->filename = fop->seq.filename_list[fop->sprite->getCurrentFrame()];
/* call the "save" procedure... did it fail? */
if (!(*fop->format->save)(fop)) {
if (!fop->format->save(fop)) {
fop_error(fop, "Error saving frame %d in the file \"%s\"\n",
fop->sprite->getCurrentFrame()+1, fop->filename.c_str());
break;
@ -654,7 +635,7 @@ void fop_operate(FileOp *fop)
/* direct save to a file */
else {
/* call the "save" procedure */
if (!(*fop->format->save)(fop))
if (!fop->format->save(fop))
fop_error(fop, "Error saving the sprite in the file \"%s\"\n",
fop->filename.c_str());
}
@ -859,16 +840,17 @@ static void fop_prepare_for_sequence(FileOp *fop)
static FileFormat *get_fileformat(const char *extension)
{
FileFormatsList::iterator it = FileFormatsManager::instance().begin();
FileFormatsList::iterator end = FileFormatsManager::instance().end();
char buf[512], *tok;
int c;
for (c=0; formats[c]; c++) {
ustrcpy(buf, formats[c]->exts);
for (; it != end; ++it) {
ustrcpy(buf, (*it)->extensions());
for (tok=ustrtok(buf, ","); tok;
tok=ustrtok(NULL, ",")) {
if (ustricmp(extension, tok) == 0)
return formats[c];
return (*it);
}
}

View File

@ -23,22 +23,10 @@
#include <vector>
#include <string>
#define FILE_SUPPORT_RGB (1<<0)
#define FILE_SUPPORT_RGBA (1<<1)
#define FILE_SUPPORT_GRAY (1<<2)
#define FILE_SUPPORT_GRAYA (1<<3)
#define FILE_SUPPORT_INDEXED (1<<4)
#define FILE_SUPPORT_LAYERS (1<<5)
#define FILE_SUPPORT_FRAMES (1<<6)
#define FILE_SUPPORT_PALETTES (1<<7)
#define FILE_SUPPORT_SEQUENCES (1<<8)
#define FILE_SUPPORT_MASKS_REPOSITORY (1<<9)
#define FILE_SUPPORT_PATHS_REPOSITORY (1<<10)
#define FILE_LOAD_SEQUENCE_NONE (1<<0)
#define FILE_LOAD_SEQUENCE_ASK (1<<1)
#define FILE_LOAD_SEQUENCE_YES (1<<2)
#define FILE_LOAD_ONE_FRAME (1<<3)
#define FILE_LOAD_SEQUENCE_NONE 0x00000001
#define FILE_LOAD_SEQUENCE_ASK 0x00000002
#define FILE_LOAD_SEQUENCE_YES 0x00000004
#define FILE_LOAD_ONE_FRAME 0x00000008
class Cel;
class Image;
@ -48,30 +36,13 @@ class Mutex;
class Palette;
class Sprite;
struct FormatOptions;
struct FileFormat;
struct FileOp;
class FileFormat;
class FormatOptions;
/* file operations */
typedef enum { FileOpLoad,
FileOpSave } FileOpType;
typedef bool (*FileLoad)(FileOp *fop);
typedef bool (*FileSave)(FileOp *fop);
typedef FormatOptions*(*GetFormatOptions)(FileOp* fop);
/* load or/and save a file format */
struct FileFormat
{
const char* name; /* file format name */
const char* exts; /* extensions (e.g. "jpeg,jpg") */
FileLoad load; /* procedure to read a sprite in this format */
FileSave save; /* procedure to write a sprite in this format */
GetFormatOptions get_options; /* procedure to configure the output format */
int flags;
};
/* structure to load & save files */
struct FileOp
{
@ -135,7 +106,7 @@ void fop_done(FileOp *fop);
void fop_stop(FileOp *fop);
void fop_free(FileOp *fop);
void fop_sequence_set_format_options(FileOp *fop, struct FormatOptions *format_options);
void fop_sequence_set_format_options(FileOp *fop, FormatOptions* format_options);
void fop_sequence_set_color(FileOp *fop, int index, int r, int g, int b);
void fop_sequence_get_color(FileOp *fop, int index, int *r, int *g, int *b);
Image* fop_sequence_image(FileOp *fi, int imgtype, int w, int h);

53
src/file/file_format.cpp Normal file
View File

@ -0,0 +1,53 @@
/* ASE - Allegro Sprite Editor
* Copyright (C) 2001-2010 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include <algorithm>
#include "file/file_format.h"
FileFormat::FileFormat()
{
}
FileFormat::~FileFormat()
{
}
const char* FileFormat::name() const
{
return onGetName();
}
const char* FileFormat::extensions() const
{
return onGetExtensions();
}
bool FileFormat::load(FileOp* fop)
{
ASSERT(support(FILE_SUPPORT_LOAD));
return onLoad(fop);
}
bool FileFormat::save(FileOp* fop)
{
ASSERT(support(FILE_SUPPORT_SAVE));
return onSave(fop);
}

82
src/file/file_format.h Normal file
View File

@ -0,0 +1,82 @@
/* ASE - Allegro Sprite Editor
* Copyright (C) 2001-2010 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef FILE_FILE_FORMAT_H_INCLUDED
#define FILE_FILE_FORMAT_H_INCLUDED
#include <vector>
#define FILE_SUPPORT_LOAD 0x00000001
#define FILE_SUPPORT_SAVE 0x00000002
#define FILE_SUPPORT_RGB 0x00000004
#define FILE_SUPPORT_RGBA 0x00000008
#define FILE_SUPPORT_GRAY 0x00000010
#define FILE_SUPPORT_GRAYA 0x00000020
#define FILE_SUPPORT_INDEXED 0x00000040
#define FILE_SUPPORT_LAYERS 0x00000080
#define FILE_SUPPORT_FRAMES 0x00000100
#define FILE_SUPPORT_PALETTES 0x00000200
#define FILE_SUPPORT_SEQUENCES 0x00000400
#define FILE_SUPPORT_MASKS_REPOSITORY 0x00000800
#define FILE_SUPPORT_PATHS_REPOSITORY 0x00001000
#define FILE_SUPPORT_GET_FORMAT_OPTIONS 0x00002000
class FormatOptions;
class FileFormat;
struct FileOp;
// A file format supported by ASE. It is the base class to extend if
// you want to add support to load and/or save a new kind of
// image/animation format.
class FileFormat
{
public:
FileFormat();
virtual ~FileFormat();
const char* name() const; // File format name
const char* extensions() const; // Extensions (e.g. "jpeg,jpg")
bool load(FileOp* fop);
bool save(FileOp* fop);
// Returns extra options for this format. It can return != NULL
// only if flags() returns FILE_SUPPORT_GET_FORMAT_OPTIONS.
FormatOptions* getFormatOptions(FileOp* fop) {
return onGetFormatOptions(fop);
}
// Returns true if this file format supports the given flag.
bool support(int f) const {
return ((onGetFlags() & f) == f);
}
protected:
virtual const char* onGetName() const = 0;
virtual const char* onGetExtensions() const = 0;
virtual int onGetFlags() const = 0;
virtual bool onLoad(FileOp* fop) = 0;
virtual bool onSave(FileOp* fop) = 0;
virtual FormatOptions* onGetFormatOptions(FileOp* fop) {
return 0;
}
};
#endif

View File

@ -0,0 +1,79 @@
/* ASE - Allegro Sprite Editor
* Copyright (C) 2001-2010 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include <algorithm>
#include "file/file_formats_manager.h"
#include "file/file_format.h"
extern FileFormat* CreateAseFormat();
extern FileFormat* CreateBmpFormat();
extern FileFormat* CreateFliFormat();
extern FileFormat* CreateGifFormat();
extern FileFormat* CreateIcoFormat();
extern FileFormat* CreateJpegFormat();
extern FileFormat* CreatePcxFormat();
extern FileFormat* CreatePngFormat();
extern FileFormat* CreateTgaFormat();
// static
FileFormatsManager& FileFormatsManager::instance()
{
static FileFormatsManager instance;
return instance;
}
FileFormatsManager::~FileFormatsManager()
{
FileFormatsList::iterator end = this->end();
for (FileFormatsList::iterator it = begin(); it != end; ++it) {
delete (*it); // delete the FileFormat
}
}
void FileFormatsManager::registerAllFormats()
{
registerFormat(CreateAseFormat());
registerFormat(CreateBmpFormat());
registerFormat(CreateFliFormat());
registerFormat(CreateGifFormat());
registerFormat(CreateIcoFormat());
registerFormat(CreateJpegFormat());
registerFormat(CreatePcxFormat());
registerFormat(CreatePngFormat());
registerFormat(CreateTgaFormat());
}
void FileFormatsManager::registerFormat(FileFormat* fileFormat)
{
m_formats.push_back(fileFormat);
}
FileFormatsList::iterator FileFormatsManager::begin()
{
return m_formats.begin();
}
FileFormatsList::iterator FileFormatsManager::end()
{
return m_formats.end();
}

View File

@ -0,0 +1,53 @@
/* ASE - Allegro Sprite Editor
* Copyright (C) 2001-2010 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef FILE_FILE_FORMATS_MANAGER_H_INCLUDED
#define FILE_FILE_FORMATS_MANAGER_H_INCLUDED
#include <vector>
class FileFormat;
// A list of file formats. Used by the FileFormatsManager to keep
// track of all known file extensions supported by ASE.
typedef std::vector<FileFormat*> FileFormatsList;
// Manages the list of known formats by ASE (image file format that can
// be loaded and/or saved).
class FileFormatsManager
{
public:
// Returns a singleton of this class.
static FileFormatsManager& instance();
virtual ~FileFormatsManager();
void registerAllFormats();
// Iterators to access to the list of formats.
FileFormatsList::iterator begin();
FileFormatsList::iterator end();
private:
// Register one format.
void registerFormat(FileFormat* fileFormat);
FileFormatsList m_formats;
};
#endif

View File

@ -22,29 +22,36 @@
#include <stdio.h>
#include "file/file.h"
#include "file/file_format.h"
#include "file/fli/fli.h"
#include "modules/palettes.h"
#include "raster/raster.h"
static bool load_FLI(FileOp *fop);
static bool save_FLI(FileOp *fop);
static int get_time_precision(Sprite *sprite);
FileFormat format_fli =
class FliFormat : public FileFormat
{
"flc",
"flc,fli",
load_FLI,
save_FLI,
NULL,
FILE_SUPPORT_INDEXED |
FILE_SUPPORT_FRAMES |
FILE_SUPPORT_PALETTES
const char* onGetName() const { return "flc"; }
const char* onGetExtensions() const { return "flc,fli"; }
int onGetFlags() const {
return
FILE_SUPPORT_LOAD |
FILE_SUPPORT_SAVE |
FILE_SUPPORT_INDEXED |
FILE_SUPPORT_FRAMES |
FILE_SUPPORT_PALETTES;
}
bool onLoad(FileOp* fop);
bool onSave(FileOp* fop);
};
/* loads a FLI/FLC file */
static bool load_FLI(FileOp *fop)
FileFormat* CreateFliFormat()
{
return new FliFormat;
}
bool FliFormat::onLoad(FileOp* fop)
{
#define SETPAL() \
do { \
@ -208,8 +215,7 @@ static bool load_FLI(FileOp *fop)
return true;
}
/* saves a FLC file */
static bool save_FLI(FileOp *fop)
bool FliFormat::onSave(FileOp* fop)
{
Sprite *sprite = fop->sprite;
unsigned char cmap[768];

View File

@ -1,69 +0,0 @@
/* ASE - Allegro Sprite Editor
* Copyright (C) 2001-2010 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include "gui/jbase.h"
#include "file/format_options.h"
FormatOptions* format_options_new(int type, int size)
{
FormatOptions* format_options;
ASSERT(size >= (int)sizeof(FormatOptions));
format_options = (FormatOptions*)jmalloc0(size);
if (format_options == NULL)
return NULL;
format_options->type = type;
format_options->size = size;
return format_options;
}
void format_options_free(FormatOptions* format_options)
{
ASSERT(format_options != NULL);
jfree(format_options);
}
BmpOptions *bmp_options_new()
{
BmpOptions *bmp_options = (BmpOptions *)
format_options_new(FORMAT_OPTIONS_BMP,
sizeof(BmpOptions));
if (bmp_options == NULL)
return NULL;
return bmp_options;
}
JpegOptions* jpeg_options_new()
{
JpegOptions *jpeg_options = (JpegOptions *)
format_options_new(FORMAT_OPTIONS_JPEG,
sizeof(JpegOptions));
if (jpeg_options == NULL)
return NULL;
return jpeg_options;
}

View File

@ -19,58 +19,13 @@
#ifndef FILE_FORMAT_OPTIONS_H_INCLUDED
#define FILE_FORMAT_OPTIONS_H_INCLUDED
enum {
FORMAT_OPTIONS_BMP,
FORMAT_OPTIONS_JPEG,
FORMAT_OPTIONS_MAX
// Extra options loaded from a file that can be useful to save the
// file later in the same loaded format (e.g. same color depth, same
// jpeg quality, etc.).
class FormatOptions
{
public:
virtual ~FormatOptions() { }
};
/* data that can be in a file and could be useful to save the file
later in the same format */
typedef struct FormatOptions
{
int type;
int size;
} FormatOptions;
FormatOptions* format_options_new(int type, int size);
void format_options_free(FormatOptions* filedata);
/*********************************************************************
Data for BMP files
*********************************************************************/
#define BMP_OPTIONS_FORMAT_WINDOWS 12
#define BMP_OPTIONS_FORMAT_OS2 40
#define BMP_OPTIONS_COMPRESSION_RGB 0
#define BMP_OPTIONS_COMPRESSION_RLE8 1
#define BMP_OPTIONS_COMPRESSION_RLE4 2
#define BMP_OPTIONS_COMPRESSION_BITFIELDS 3
typedef struct BmpOptions
{
FormatOptions head;
int format; /* BMP format */
int compression; /* BMP compression */
int bits_per_pixel; /* bits per pixel */
ase_uint32 red_mask; /* mask for red channel */
ase_uint32 green_mask; /* mask for green channel */
ase_uint32 blue_mask; /* mask for blue channel */
} BmpOptions;
BmpOptions *bmp_options_new();
/*********************************************************************
Data for JPEG files
*********************************************************************/
typedef struct JpegOptions
{
FormatOptions head;
float quality; /* 1.0 maximum quality */
} JpegOptions;
JpegOptions* jpeg_options_new();
#endif

View File

@ -30,6 +30,7 @@
#include "gui/jbase.h"
#include "file/file.h"
#include "file/file_format.h"
#include "file/gif/format.h"
#include "modules/palettes.h"
#include "raster/raster.h"
@ -38,21 +39,28 @@
#include <stdio.h>
#include <stdlib.h>
static bool load_GIF(FileOp *fop);
static bool save_GIF(FileOp *fop);
FileFormat format_gif =
class GifFormat : public FileFormat
{
"gif",
"gif",
load_GIF,
save_GIF,
NULL,
FILE_SUPPORT_INDEXED |
FILE_SUPPORT_FRAMES |
FILE_SUPPORT_PALETTES
const char* onGetName() const { return "gif"; }
const char* onGetExtensions() const { return "gif"; }
int onGetFlags() const {
return
FILE_SUPPORT_LOAD |
FILE_SUPPORT_SAVE |
FILE_SUPPORT_INDEXED |
FILE_SUPPORT_FRAMES |
FILE_SUPPORT_PALETTES;
}
bool onLoad(FileOp* fop);
bool onSave(FileOp* fop);
};
FileFormat* CreateGifFormat()
{
return new GifFormat;
}
static void render_gif_frame(GIF_FRAME *frame, Image *image,
int x, int y, int w, int h)
{
@ -70,10 +78,7 @@ static void render_gif_frame(GIF_FRAME *frame, Image *image,
}
}
/* load_GIF:
* Loads a GIF into a sprite.
*/
static bool load_GIF(FileOp *fop)
bool GifFormat::onLoad(FileOp* fop)
{
GIF_ANIMATION *gif = NULL;
Sprite *sprite = NULL;
@ -278,13 +283,8 @@ static int max_used_index(Image *image)
return max;
}
/* save_gif:
* Writes a sprite into a GIF file.
*
* TODO: transparent index is not stored. And reserve a single color
* as transparent.
*/
static bool save_GIF(FileOp *fop)
// TODO: transparent index is not stored. And reserve a single color as transparent.
bool GifFormat::onSave(FileOp* fop)
{
Sprite *sprite = fop->sprite;
GIF_ANIMATION *gif;

View File

@ -23,23 +23,31 @@
#include <allegro/color.h>
#include "file/file.h"
#include "file/file_format.h"
#include "raster/raster.h"
static bool load_ICO(FileOp* fop);
static bool save_ICO(FileOp* fop);
FileFormat format_ico =
class IcoFormat : public FileFormat
{
"ico",
"ico",
load_ICO,
save_ICO,
NULL,
FILE_SUPPORT_RGB |
FILE_SUPPORT_GRAY |
FILE_SUPPORT_INDEXED
const char* onGetName() const { return "ico"; }
const char* onGetExtensions() const { return "ico"; }
int onGetFlags() const {
return
FILE_SUPPORT_LOAD |
FILE_SUPPORT_SAVE |
FILE_SUPPORT_RGB |
FILE_SUPPORT_GRAY |
FILE_SUPPORT_INDEXED;
}
bool onLoad(FileOp* fop);
bool onSave(FileOp* fop);
};
FileFormat* CreateIcoFormat()
{
return new IcoFormat;
}
struct ICONDIR
{
ase_uint16 reserved;
@ -74,7 +82,7 @@ struct BITMAPINFOHEADER
ase_uint32 clrImportant;
};
static bool load_ICO(FileOp *fop)
bool IcoFormat::onLoad(FileOp* fop)
{
FILE* f = fopen(fop->filename.c_str(), "rb");
if (!f)
@ -226,7 +234,7 @@ static bool load_ICO(FileOp *fop)
return true;
}
static bool save_ICO(FileOp *fop)
bool IcoFormat::onSave(FileOp* fop)
{
Sprite *sprite = fop->sprite;
int bpp, bw, bitsw;

View File

@ -27,28 +27,45 @@
#include "app.h"
#include "core/cfg.h"
#include "file/file.h"
#include "file/file_format.h"
#include "file/format_options.h"
#include "modules/gui.h"
#include "raster/raster.h"
#include "jpeglib.h"
static bool load_JPEG(FileOp *fop);
static bool save_JPEG(FileOp *fop);
static FormatOptions *get_options_JPEG(FileOp *fop);
FileFormat format_jpeg =
class JpegFormat : public FileFormat
{
"jpeg",
"jpeg,jpg",
load_JPEG,
save_JPEG,
get_options_JPEG,
FILE_SUPPORT_RGB |
FILE_SUPPORT_GRAY |
FILE_SUPPORT_SEQUENCES
// Data for JPEG files
class JpegOptions : public FormatOptions
{
public:
float quality; /* 1.0 maximum quality */
};
const char* onGetName() const { return "jpeg"; }
const char* onGetExtensions() const { return "jpeg,jpg"; }
int onGetFlags() const {
return
FILE_SUPPORT_LOAD |
FILE_SUPPORT_SAVE |
FILE_SUPPORT_RGB |
FILE_SUPPORT_GRAY |
FILE_SUPPORT_SEQUENCES |
FILE_SUPPORT_GET_FORMAT_OPTIONS;
}
bool onLoad(FileOp* fop);
bool onSave(FileOp* fop);
FormatOptions* onGetFormatOptions(FileOp* fop);
};
FileFormat* CreateJpegFormat()
{
return new JpegFormat;
}
struct error_mgr {
struct jpeg_error_mgr head;
jmp_buf setjmp_buffer;
@ -78,7 +95,7 @@ static void output_message(j_common_ptr cinfo)
fop_error(((struct error_mgr *)cinfo->err)->fop, "%s\n", buffer);
}
static bool load_JPEG(FileOp *fop)
bool JpegFormat::onLoad(FileOp* fop)
{
struct jpeg_decompress_struct cinfo;
struct error_mgr jerr;
@ -220,7 +237,7 @@ static bool load_JPEG(FileOp *fop)
return true;
}
static bool save_JPEG(FileOp *fop)
bool JpegFormat::onSave(FileOp* fop)
{
struct jpeg_compress_struct cinfo;
struct error_mgr jerr;
@ -344,12 +361,10 @@ static bool save_JPEG(FileOp *fop)
return true;
}
/**
* Shows the JPEG configuration dialog.
*/
static FormatOptions *get_options_JPEG(FileOp *fop)
// Shows the JPEG configuration dialog.
FormatOptions* JpegFormat::onGetFormatOptions(FileOp* fop)
{
JpegOptions* jpeg_options = jpeg_options_new();
JpegOptions* jpeg_options = new JpegOptions();
try {
// Configuration parameters
jpeg_options->quality = get_config_float("JPEG", "Quality", 1.0f);
@ -375,14 +390,14 @@ static FormatOptions *get_options_JPEG(FileOp *fop)
set_config_float("JPEG", "Quality", jpeg_options->quality);
}
else {
format_options_free((FormatOptions *)jpeg_options);
delete jpeg_options;
jpeg_options = NULL;
}
return (FormatOptions *)jpeg_options;
return jpeg_options;
}
catch (ase_exception& e) {
format_options_free((FormatOptions *)jpeg_options);
delete jpeg_options;
e.show();
return NULL;

View File

@ -23,25 +23,33 @@
#include <allegro/color.h>
#include "file/file.h"
#include "file/file_format.h"
#include "raster/raster.h"
static bool load_PCX(FileOp *fop);
static bool save_PCX(FileOp *fop);
FileFormat format_pcx =
class PcxFormat : public FileFormat
{
"pcx",
"pcx",
load_PCX,
save_PCX,
NULL,
FILE_SUPPORT_RGB |
FILE_SUPPORT_GRAY |
FILE_SUPPORT_INDEXED |
FILE_SUPPORT_SEQUENCES
const char* onGetName() const { return "pcx"; }
const char* onGetExtensions() const { return "pcx"; }
int onGetFlags() const {
return
FILE_SUPPORT_LOAD |
FILE_SUPPORT_SAVE |
FILE_SUPPORT_RGB |
FILE_SUPPORT_GRAY |
FILE_SUPPORT_INDEXED |
FILE_SUPPORT_SEQUENCES;
}
bool onLoad(FileOp* fop);
bool onSave(FileOp* fop);
};
static bool load_PCX(FileOp *fop)
FileFormat* CreatePcxFormat()
{
return new PcxFormat;
}
bool PcxFormat::onLoad(FileOp* fop)
{
Image *image;
FILE *f;
@ -176,7 +184,7 @@ static bool load_PCX(FileOp *fop)
}
}
static bool save_PCX(FileOp *fop)
bool PcxFormat::onSave(FileOp* fop)
{
Image *image = fop->seq.image;
FILE *f;

View File

@ -24,35 +24,43 @@
#include "app.h"
#include "core/cfg.h"
#include "file/file.h"
#include "file/file_format.h"
#include "raster/raster.h"
#define PNG_NO_TYPECAST_NULL
#include "png.h"
static bool load_PNG(FileOp *fop);
static bool save_PNG(FileOp *fop);
FileFormat format_png =
class PngFormat : public FileFormat
{
"png",
"png",
load_PNG,
save_PNG,
NULL,
FILE_SUPPORT_RGB |
FILE_SUPPORT_RGBA |
FILE_SUPPORT_GRAY |
FILE_SUPPORT_GRAYA |
FILE_SUPPORT_INDEXED |
FILE_SUPPORT_SEQUENCES
const char* onGetName() const { return "png"; }
const char* onGetExtensions() const { return "png"; }
int onGetFlags() const {
return
FILE_SUPPORT_LOAD |
FILE_SUPPORT_SAVE |
FILE_SUPPORT_RGB |
FILE_SUPPORT_RGBA |
FILE_SUPPORT_GRAY |
FILE_SUPPORT_GRAYA |
FILE_SUPPORT_INDEXED |
FILE_SUPPORT_SEQUENCES;
}
bool onLoad(FileOp* fop);
bool onSave(FileOp* fop);
};
FileFormat* CreatePngFormat()
{
return new PngFormat;
}
static void report_png_error(png_structp png_ptr, png_const_charp error)
{
fop_error((FileOp *)png_ptr->error_ptr, "libpng: %s\n", error);
}
static bool load_PNG(FileOp *fop)
bool PngFormat::onLoad(FileOp* fop)
{
png_uint_32 width, height, y;
unsigned int sig_read = 0;
@ -314,7 +322,7 @@ static bool load_PNG(FileOp *fop)
return true;
}
static bool save_PNG(FileOp *fop)
bool PngFormat::onSave(FileOp* fop)
{
Image *image = fop->seq.image;
png_uint_32 width, height, y;

View File

@ -26,25 +26,33 @@
#include "gui/jbase.h"
#include "file/file.h"
#include "file/file_format.h"
#include "raster/raster.h"
static bool load_TGA(FileOp *fop);
static bool save_TGA(FileOp *fop);
FileFormat format_tga =
class TgaFormat : public FileFormat
{
"tga",
"tga",
load_TGA,
save_TGA,
NULL,
FILE_SUPPORT_RGB |
FILE_SUPPORT_RGBA |
FILE_SUPPORT_GRAY |
FILE_SUPPORT_INDEXED |
FILE_SUPPORT_SEQUENCES
const char* onGetName() const { return "tga"; }
const char* onGetExtensions() const { return "tga"; }
int onGetFlags() const {
return
FILE_SUPPORT_LOAD |
FILE_SUPPORT_SAVE |
FILE_SUPPORT_RGB |
FILE_SUPPORT_RGBA |
FILE_SUPPORT_GRAY |
FILE_SUPPORT_INDEXED |
FILE_SUPPORT_SEQUENCES;
}
bool onLoad(FileOp* fop);
bool onSave(FileOp* fop);
};
FileFormat* CreateTgaFormat()
{
return new TgaFormat;
}
/* rle_tga_read:
* Helper for reading 256 color RLE data from TGA files.
*/
@ -186,7 +194,7 @@ static void rle_tga_read16(ase_uint32 *address, int w, FILE *f)
* structure and storing the palette data in the specified palette (this
* should be an array of at least 256 RGB structures).
*/
static bool load_TGA(FileOp *fop)
bool TgaFormat::onLoad(FileOp* fop)
{
unsigned char image_id[256], image_palette[256][3], rgb[4];
unsigned char id_length, palette_type, image_type, palette_entry_size;
@ -396,7 +404,7 @@ static bool load_TGA(FileOp *fop)
* Writes a bitmap into a TGA file, using the specified palette (this
* should be an array of at least 256 RGB structures).
*/
static bool save_TGA(FileOp *fop)
bool TgaFormat::onSave(FileOp* fop)
{
Image *image = fop->seq.image;
unsigned char image_palette[256][3];

View File

@ -301,9 +301,7 @@ public:
}
void setFormatOptions(FormatOptions* format_options) {
if (m_format_options)
jfree(m_format_options);
delete m_format_options;
m_format_options = format_options;
}
@ -600,8 +598,7 @@ SpriteImpl::~SpriteImpl()
delete m_mutex;
// Destroy file format options
if (m_format_options)
format_options_free(m_format_options);
delete m_format_options;
delete m_rgbMap;
}

View File

@ -22,7 +22,7 @@
#include "raster/gfxobj.h"
#include <vector>
struct FormatOptions;
class FormatOptions;
class Image;
class Layer;
class LayerFolder;