Add FileHandle to avoid manual FILE handle management.

This commit is contained in:
David Capello 2012-05-03 00:32:40 -03:00
parent 97154d5fbc
commit 9b4621be31
9 changed files with 70 additions and 129 deletions

View File

@ -22,6 +22,7 @@
#include "document.h"
#include "file/file.h"
#include "file/file_format.h"
#include "file/file_handle.h"
#include "file/format_options.h"
#include "gui/list.h"
#include "raster/raster.h"
@ -143,12 +144,10 @@ bool AseFormat::onLoad(FileOp *fop)
int chunk_type;
int c, frame;
FILE* f = fopen(fop->filename.c_str(), "rb");
FileHandle f(fop->filename.c_str(), "rb");
if (!f)
return false;
UniquePtr<FILE, int(*)(FILE*)> fileHandleWrapper(f, fclose);
if (!ase_file_read_header(f, &header)) {
fop_error(fop, "Error reading header\n");
return false;
@ -297,13 +296,8 @@ bool AseFormat::onSave(FileOp *fop)
ASE_Header header;
ASE_FrameHeader frame_header;
int frame;
FILE *f;
f = fopen(fop->filename.c_str(), "wb");
if (!f)
return false;
UniquePtr<FILE, int(*)(FILE*)> fileHandleWrapper(f, fclose);
FileHandle f(fop->filename.c_str(), "wb");
/* prepare the header */
ase_file_prepare_header(f, &header, sprite);

View File

@ -22,6 +22,7 @@
#include "file/file.h"
#include "file/file_format.h"
#include "file/file_handle.h"
#include "file/format_options.h"
#include "raster/raster.h"
@ -601,19 +602,16 @@ bool BmpFormat::onLoad(FileOp *fop)
BITMAPFILEHEADER fileheader;
BITMAPINFOHEADER infoheader;
Image *image;
FILE *f;
unsigned long biSize;
PixelFormat pixelFormat;
int format;
f = fopen(fop->filename.c_str(), "rb");
FileHandle f(fop->filename.c_str(), "rb");
if (!f)
return false;
if (read_bmfileheader(f, &fileheader) != 0) {
fclose(f);
if (read_bmfileheader(f, &fileheader) != 0)
return false;
}
biSize = fgetl(f);
@ -621,7 +619,6 @@ bool BmpFormat::onLoad(FileOp *fop)
format = BMP_OPTIONS_FORMAT_WINDOWS;
if (read_win_bminfoheader(f, &infoheader) != 0) {
fclose(f);
return false;
}
if (infoheader.biCompression != BI_BITFIELDS)
@ -631,7 +628,6 @@ bool BmpFormat::onLoad(FileOp *fop)
format = BMP_OPTIONS_FORMAT_OS2;
if (read_os2_bminfoheader(f, &infoheader) != 0) {
fclose(f);
return false;
}
/* compute number of colors recorded */
@ -639,7 +635,6 @@ bool BmpFormat::onLoad(FileOp *fop)
read_bmicolors(fop, fileheader.bfOffBits - 26, f, false);
}
else {
fclose(f);
return false;
}
@ -663,7 +658,6 @@ bool BmpFormat::onLoad(FileOp *fop)
infoheader.biWidth,
ABS((int)infoheader.biHeight));
if (!image) {
fclose(f);
return false;
}
@ -690,20 +684,17 @@ bool BmpFormat::onLoad(FileOp *fop)
if (read_bitfields_image(f, image, &infoheader, rmask, gmask, bmask) < 0) {
image_free(image);
fop_error(fop, "Unsupported bitfields in the BMP file.\n");
fclose(f);
return false;
}
break;
default:
fop_error(fop, "Unsupported BMP compression.\n");
fclose(f);
return false;
}
if (ferror(f)) {
fop_error(fop, "Error reading file.\n");
fclose(f);
return false;
}
@ -721,14 +712,12 @@ bool BmpFormat::onLoad(FileOp *fop)
fop_sequence_set_format_options(fop, bmp_options);
}
fclose(f);
return true;
}
bool BmpFormat::onSave(FileOp *fop)
{
Image *image = fop->seq.image;
FILE *f;
int bfSize;
int biSizeImage;
int bpp = (image->getPixelFormat() == IMAGE_RGB) ? 24 : 8;
@ -746,7 +735,7 @@ bool BmpFormat::onSave(FileOp *fop)
bfSize = 54 + biSizeImage; /* header + image data */
}
f = fopen(fop->filename.c_str(), "wb");
FileHandle f(fop->filename.c_str(), "wb");
if (!f) {
fop_error(fop, "Error creating file.\n");
return false;
@ -817,11 +806,9 @@ bool BmpFormat::onSave(FileOp *fop)
if (ferror(f)) {
fop_error(fop, "Error writing file.\n");
fclose(f);
return false;
}
else {
fclose(f);
return true;
}
}

44
src/file/file_handle.h Normal file
View File

@ -0,0 +1,44 @@
/* ASEPRITE
* Copyright (C) 2001-2012 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_HANDLE_FORMAT_H_INCLUDED
#define FILE_HANDLE_FORMAT_H_INCLUDED
#include "base/exception.h"
#include "base/unique_ptr.h"
#include <cstdio>
#include <string>
class FileHandle
{
public:
FileHandle(const char* fileName, const char* mode)
: m_handle(std::fopen(fileName, mode), std::fclose)
{
if (!m_handle)
throw base::Exception(std::string("Cannot open ") + fileName);
}
operator std::FILE*() { return m_handle; }
private:
UniquePtr<std::FILE, int(*)(std::FILE*)> m_handle;
};
#endif

View File

@ -21,6 +21,7 @@
#include "document.h"
#include "file/file.h"
#include "file/file_format.h"
#include "file/file_handle.h"
#include "file/fli/fli.h"
#include "file/format_options.h"
#include "modules/palettes.h"
@ -78,19 +79,15 @@ bool FliFormat::onLoad(FileOp* fop)
int frpos_out;
int index = 0;
Cel *cel;
FILE *f;
/* open the file to read in binary mode */
f = fopen(fop->filename.c_str(), "rb");
if (!f)
return false;
FileHandle f(fop->filename.c_str(), "rb");
fli_read_header(f, &fli_header);
fseek(f, 128, SEEK_SET);
if (fli_header.magic == NO_HEADER) {
fop_error(fop, "The file doesn't have a FLIC header\n");
fclose(f);
return false;
}
@ -107,7 +104,6 @@ bool FliFormat::onLoad(FileOp* fop)
if (bmp) image_free(bmp);
if (old) image_free(old);
if (pal) delete pal;
fclose(f);
return false;
}
@ -196,9 +192,6 @@ bool FliFormat::onLoad(FileOp* fop)
// Update number of frames
sprite->setTotalFrames(frpos_out+1);
// Close the file
fclose(f);
// Destroy the bitmaps
image_free(bmp);
image_free(old);
@ -217,7 +210,6 @@ bool FliFormat::onSave(FileOp* fop)
int c, frpos, times;
Image *bmp, *old;
Palette *pal;
FILE *f;
/* prepare fli header */
fli_header.filesize = 0;
@ -240,9 +232,7 @@ bool FliFormat::onSave(FileOp* fop)
fli_header.oframe1 = fli_header.oframe2 = 0;
/* open the file to write in binary mode */
f = fopen(fop->filename.c_str(), "wb");
if (!f)
return false;
FileHandle f(fop->filename.c_str(), "wb");
fseek(f, 128, SEEK_SET);
@ -253,7 +243,6 @@ bool FliFormat::onSave(FileOp* fop)
fop_error(fop, "Not enough memory for temporary bitmaps.\n");
if (bmp) image_free(bmp);
if (old) image_free(old);
fclose(f);
return false;
}
@ -298,7 +287,6 @@ bool FliFormat::onSave(FileOp* fop)
/* write the header and close the file */
fli_write_header(f, &fli_header);
fclose(f);
/* destroy the bitmaps */
image_free(bmp);

View File

@ -23,6 +23,7 @@
#include "document.h"
#include "file/file.h"
#include "file/file_format.h"
#include "file/file_handle.h"
#include "file/format_options.h"
#include "raster/raster.h"
@ -86,9 +87,7 @@ struct BITMAPINFOHEADER
bool IcoFormat::onLoad(FileOp* fop)
{
FILE* f = fopen(fop->filename.c_str(), "rb");
if (!f)
return false;
FileHandle f(fop->filename.c_str(), "rb");
// Read the icon header
ICONDIR header;
@ -98,13 +97,11 @@ bool IcoFormat::onLoad(FileOp* fop)
if (header.type != 1) {
fop_error(fop, "Invalid ICO file type.\n");
fclose(f);
return false;
}
if (header.entries < 1) {
fop_error(fop, "This ICO files does not contain images.\n");
fclose(f);
return false;
}
@ -230,9 +227,6 @@ bool IcoFormat::onLoad(FileOp* fop)
}
}
// Close the file
fclose(f);
fop->document = new Document(sprite);
return true;
}
@ -245,9 +239,7 @@ bool IcoFormat::onSave(FileOp* fop)
int c, x, y, b, m, v;
int num = sprite->getTotalFrames();
FILE* f = fopen(fop->filename.c_str(), "wb");
if (!f)
return false;
FileHandle f(fop->filename.c_str(), "wb");
offset = 6 + num*16; // ICONDIR + ICONDIRENTRYs
@ -397,7 +389,6 @@ bool IcoFormat::onSave(FileOp* fop)
}
image_free(image);
fclose(f);
return true;
}

View File

@ -28,6 +28,7 @@
#include "console.h"
#include "file/file.h"
#include "file/file_format.h"
#include "file/file_handle.h"
#include "file/format_options.h"
#include "gui/gui.h"
#include "ini_file.h"
@ -102,13 +103,12 @@ bool JpegFormat::onLoad(FileOp* fop)
struct jpeg_decompress_struct cinfo;
struct error_mgr jerr;
Image *image;
FILE *file;
JDIMENSION num_scanlines;
JSAMPARRAY buffer;
JDIMENSION buffer_height;
int c;
file = fopen(fop->filename.c_str(), "rb");
FileHandle file(fop->filename.c_str(), "rb");
if (!file)
return false;
@ -122,7 +122,6 @@ bool JpegFormat::onLoad(FileOp* fop)
// Establish the setjmp return context for error_exit to use.
if (setjmp(jerr.setjmp_buffer)) {
jpeg_destroy_decompress(&cinfo);
fclose(file);
return false;
}
@ -150,7 +149,6 @@ bool JpegFormat::onLoad(FileOp* fop)
cinfo.output_height);
if (!image) {
jpeg_destroy_decompress(&cinfo);
fclose(file);
return false;
}
@ -159,7 +157,6 @@ bool JpegFormat::onLoad(FileOp* fop)
buffer = (JSAMPARRAY)base_malloc(sizeof(JSAMPROW) * buffer_height);
if (!buffer) {
jpeg_destroy_decompress(&cinfo);
fclose(file);
return false;
}
@ -171,7 +168,6 @@ bool JpegFormat::onLoad(FileOp* fop)
base_free(buffer[c]);
base_free(buffer);
jpeg_destroy_decompress(&cinfo);
fclose(file);
return false;
}
}
@ -235,7 +231,6 @@ bool JpegFormat::onLoad(FileOp* fop)
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
fclose(file);
return true;
}
@ -244,14 +239,13 @@ bool JpegFormat::onSave(FileOp* fop)
struct jpeg_compress_struct cinfo;
struct error_mgr jerr;
Image *image = fop->seq.image;
FILE *file;
JSAMPARRAY buffer;
JDIMENSION buffer_height;
SharedPtr<JpegOptions> jpeg_options = fop->seq.format_options;
int c;
// Open the file for write in it.
file = fopen(fop->filename.c_str(), "wb");
FileHandle file(fop->filename.c_str(), "wb");
if (!file) {
fop_error(fop, "Error creating file.\n");
return false;
@ -292,7 +286,6 @@ bool JpegFormat::onSave(FileOp* fop)
if (!buffer) {
fop_error(fop, "Not enough memory for the buffer.\n");
jpeg_destroy_compress(&cinfo);
fclose(file);
return false;
}
@ -305,7 +298,6 @@ bool JpegFormat::onSave(FileOp* fop)
base_free(buffer[c]);
base_free(buffer);
jpeg_destroy_compress(&cinfo);
fclose(file);
return false;
}
}
@ -356,9 +348,6 @@ bool JpegFormat::onSave(FileOp* fop)
// Release JPEG compression object.
jpeg_destroy_compress(&cinfo);
// We can close the output file.
fclose(file);
// All fine.
return true;
}

View File

@ -22,6 +22,7 @@
#include "file/file.h"
#include "file/file_format.h"
#include "file/file_handle.h"
#include "file/format_options.h"
#include "raster/raster.h"
@ -53,7 +54,6 @@ FileFormat* CreatePcxFormat()
bool PcxFormat::onLoad(FileOp* fop)
{
Image *image;
FILE *f;
int c, r, g, b;
int width, height;
int bpp, bytes_per_line;
@ -61,9 +61,7 @@ bool PcxFormat::onLoad(FileOp* fop)
int x, y;
char ch = 0;
f = fopen(fop->filename.c_str(), "rb");
if (!f)
return false;
FileHandle f(fop->filename.c_str(), "rb");
fgetc(f); /* skip manufacturer ID */
fgetc(f); /* skip version flag */
@ -71,7 +69,6 @@ bool PcxFormat::onLoad(FileOp* fop)
if (fgetc(f) != 8) { /* we like 8 bit color planes */
fop_error(fop, "This PCX doesn't have 8 bit color planes.\n");
fclose(f);
return false;
}
@ -93,7 +90,6 @@ bool PcxFormat::onLoad(FileOp* fop)
bpp = fgetc(f) * 8; /* how many color planes? */
if ((bpp != 8) && (bpp != 24)) {
fclose(f);
return false;
}
@ -107,7 +103,6 @@ bool PcxFormat::onLoad(FileOp* fop)
IMAGE_RGB,
width, height);
if (!image) {
fclose(f);
return false;
}
@ -176,11 +171,9 @@ bool PcxFormat::onLoad(FileOp* fop)
if (ferror(f)) {
fop_error(fop, "Error reading file.\n");
fclose(f);
return false;
}
else {
fclose(f);
return true;
}
}
@ -188,7 +181,6 @@ bool PcxFormat::onLoad(FileOp* fop)
bool PcxFormat::onSave(FileOp* fop)
{
Image *image = fop->seq.image;
FILE *f;
int c, r, g, b;
int x, y;
int runcount;
@ -196,11 +188,7 @@ bool PcxFormat::onSave(FileOp* fop)
char runchar;
char ch = 0;
f = fopen(fop->filename.c_str(), "wb");
if (!f) {
fop_error(fop, "Error creating file.\n");
return false;
}
FileHandle f(fop->filename.c_str(), "wb");
if (image->getPixelFormat() == IMAGE_RGB) {
depth = 24;
@ -302,11 +290,9 @@ bool PcxFormat::onSave(FileOp* fop)
if (ferror(f)) {
fop_error(fop, "Error writing file.\n");
fclose(f);
return false;
}
else {
fclose(f);
return true;
}
}

View File

@ -22,6 +22,7 @@
#include "document.h"
#include "file/file.h"
#include "file/file_format.h"
#include "file/file_handle.h"
#include "file/format_options.h"
#include "ini_file.h"
#include "raster/raster.h"
@ -73,12 +74,9 @@ bool PngFormat::onLoad(FileOp* fop)
png_colorp palette;
png_bytep row_pointer;
Image *image;
FILE *fp;
PixelFormat pixelFormat;
fp = fopen(fop->filename.c_str(), "rb");
if (!fp)
return false;
FileHandle fp(fop->filename.c_str(), "rb");
/* Create and initialize the png_struct with the desired error handler
* functions. If you want to use the default stderr and longjump method,
@ -90,7 +88,6 @@ bool PngFormat::onLoad(FileOp* fop)
report_png_error, report_png_error);
if (png_ptr == NULL) {
fop_error(fop, "png_create_read_struct\n");
fclose(fp);
return false;
}
@ -98,7 +95,6 @@ bool PngFormat::onLoad(FileOp* fop)
info_ptr = png_create_info_struct(png_ptr);
if (info_ptr == NULL) {
fop_error(fop, "png_create_info_struct\n");
fclose(fp);
png_destroy_read_struct(&png_ptr, NULL, NULL);
return false;
}
@ -110,7 +106,6 @@ bool PngFormat::onLoad(FileOp* fop)
fop_error(fop, "Error reading PNG file\n");
/* Free all of the memory associated with the png_ptr and info_ptr */
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
fclose(fp);
/* If we get here, we had a problem reading the file */
return false;
}
@ -181,7 +176,6 @@ bool PngFormat::onLoad(FileOp* fop)
default:
fop_error(fop, "Color type not supported\n)");
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
fclose(fp);
return false;
}
@ -191,7 +185,6 @@ bool PngFormat::onLoad(FileOp* fop)
if (!image) {
fop_error(fop, "file_sequence_image %dx%d\n", imageWidth, imageHeight);
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
fclose(fp);
return false;
}
@ -327,9 +320,6 @@ bool PngFormat::onLoad(FileOp* fop)
/* clean up after the read, and free any memory allocated */
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
/* close the file */
fclose(fp);
return true;
}
@ -343,12 +333,9 @@ bool PngFormat::onSave(FileOp* fop)
png_bytep row_pointer;
int color_type = 0;
int pass, number_passes;
FILE *fp;
/* open the file */
fp = fopen(fop->filename.c_str(), "wb");
if (fp == NULL)
return false;
FileHandle fp(fop->filename.c_str(), "wb");
/* Create and initialize the png_struct with the desired error handler
* functions. If you want to use the default stderr and longjump method,
@ -359,14 +346,12 @@ bool PngFormat::onSave(FileOp* fop)
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, (png_voidp)fop,
report_png_error, report_png_error);
if (png_ptr == NULL) {
fclose(fp);
return false;
}
/* Allocate/initialize the image information data. REQUIRED */
info_ptr = png_create_info_struct(png_ptr);
if (info_ptr == NULL) {
fclose(fp);
png_destroy_write_struct(&png_ptr, NULL);
return false;
}
@ -376,7 +361,6 @@ bool PngFormat::onSave(FileOp* fop)
*/
if (setjmp(png_jmpbuf(png_ptr))) {
/* If we get here, we had a problem reading the file */
fclose(fp);
png_destroy_write_struct(&png_ptr, &info_ptr);
return false;
}
@ -552,9 +536,6 @@ bool PngFormat::onSave(FileOp* fop)
/* clean up after the write, and free any memory allocated */
png_destroy_write_struct(&png_ptr, &info_ptr);
/* close the file */
fclose(fp);
/* all right */
return true;
}

View File

@ -23,6 +23,7 @@
#include "file/file.h"
#include "file/file_format.h"
#include "file/file_handle.h"
#include "file/format_options.h"
#include "raster/raster.h"
@ -203,11 +204,8 @@ bool TgaFormat::onLoad(FileOp* fop)
unsigned int c, i, x, y, yc;
Image *image;
int compressed;
FILE *f;
f = fopen(fop->filename.c_str(), "rb");
if (!f)
return false;
FileHandle f(fop->filename.c_str(), "rb");
id_length = fgetc(f);
palette_type = fgetc(f);
@ -247,7 +245,6 @@ bool TgaFormat::onLoad(FileOp* fop)
}
}
else if (palette_type != 0) {
fclose(f);
return false;
}
@ -270,7 +267,6 @@ bool TgaFormat::onLoad(FileOp* fop)
/* paletted image */
case 1:
if ((palette_type != 1) || (bpp != 8)) {
fclose(f);
return false;
}
@ -289,7 +285,6 @@ bool TgaFormat::onLoad(FileOp* fop)
if ((palette_type != 0) ||
((bpp != 15) && (bpp != 16) &&
(bpp != 24) && (bpp != 32))) {
fclose(f);
return false;
}
@ -299,7 +294,6 @@ bool TgaFormat::onLoad(FileOp* fop)
/* grayscale image */
case 3:
if ((palette_type != 0) || (bpp != 8)) {
fclose(f);
return false;
}
@ -311,16 +305,12 @@ bool TgaFormat::onLoad(FileOp* fop)
default:
/* TODO add support for more TGA types? */
fclose(f);
return false;
}
image = fop_sequence_image(fop, pixelFormat, image_width, image_height);
if (!image) {
fclose(f);
if (!image)
return false;
}
for (y=image_height; y; y--) {
yc = (descriptor_bits & 0x20) ? image_height-y : y-1;
@ -391,11 +381,9 @@ bool TgaFormat::onLoad(FileOp* fop)
if (ferror(f)) {
fop_error(fop, "Error reading file.\n");
fclose(f);
return false;
}
else {
fclose(f);
return true;
}
}
@ -411,13 +399,8 @@ bool TgaFormat::onSave(FileOp* fop)
int x, y, c, r, g, b;
int depth = (image->getPixelFormat() == IMAGE_RGB) ? 32 : 8;
bool need_pal = (image->getPixelFormat() == IMAGE_INDEXED)? true: false;
FILE *f;
f = fopen(fop->filename.c_str(), "wb");
if (!f) {
fop_error(fop, "Error creating file.\n");
return false;
}
FileHandle f(fop->filename.c_str(), "wb");
fputc(0, f); /* id length (no id saved) */
fputc((need_pal) ? 1 : 0, f); /* palette type */
@ -484,11 +467,9 @@ bool TgaFormat::onSave(FileOp* fop)
if (ferror(f)) {
fop_error(fop, "Error writing file.\n");
fclose(f);
return false;
}
else {
fclose(f);
return true;
}
}