plug-ins/file-bmp/bmp.[ch] plug-ins/file-bmp/bmp-read.c for most errors,

2008-08-19  Sven Neumann  <sven@gimp.org>

	* plug-ins/file-bmp/bmp.[ch]
	* plug-ins/file-bmp/bmp-read.c
	* plug-ins/file-bmp/bmp-write.c: for most errors, pass the error
	message with the return values instead of calling g_message().


svn path=/trunk/; revision=26657
This commit is contained in:
Sven Neumann
2008-08-19 06:27:32 +00:00
committed by Sven Neumann
parent 369d991fd2
commit 6e23a26307
5 changed files with 144 additions and 91 deletions

View File

@ -1,3 +1,10 @@
2008-08-19 Sven Neumann <sven@gimp.org>
* plug-ins/file-bmp/bmp.[ch]
* plug-ins/file-bmp/bmp-read.c
* plug-ins/file-bmp/bmp-write.c: for most errors, pass the error
message with the return values instead of calling g_message().
2008-08-19 Sven Neumann <sven@gimp.org> 2008-08-19 Sven Neumann <sven@gimp.org>
Complements the fix for bug #344818: Complements the fix for bug #344818:

View File

@ -42,16 +42,17 @@
#define BI_BITFIELDS 3 #define BI_BITFIELDS 3
#endif #endif
static gint32 ReadImage (FILE *fd, static gint32 ReadImage (FILE *fd,
gint width, gint width,
gint height, gint height,
guchar cmap[256][3], guchar cmap[256][3],
gint ncols, gint ncols,
gint bpp, gint bpp,
gint compression, gint compression,
gint rowbytes, gint rowbytes,
gboolean grey, gboolean grey,
const Bitmap_Channel *masks); const Bitmap_Channel *masks,
GError **error);
static gint32 static gint32
@ -93,6 +94,7 @@ ReadColorMap (FILE *fd,
buffer[i][2] = rgb[0]; buffer[i][2] = rgb[0];
*grey = ((*grey) && (rgb[0]==rgb[1]) && (rgb[1]==rgb[2])); *grey = ((*grey) && (rgb[0]==rgb[1]) && (rgb[1]==rgb[2]));
} }
return TRUE; return TRUE;
} }
@ -126,11 +128,13 @@ ReadChannelMasks (guint32 *tmp, Bitmap_Channel *masks, guint channels)
i, masks[i].mask, masks[i].shiftin, (gint)masks[i].max_value); i, masks[i].mask, masks[i].shiftin, (gint)masks[i].max_value);
#endif #endif
} }
return TRUE; return TRUE;
} }
gint32 gint32
ReadBMP (const gchar *name) ReadBMP (const gchar *name,
GError **error)
{ {
FILE *fd; FILE *fd;
guchar buffer[64]; guchar buffer[64];
@ -146,8 +150,9 @@ ReadBMP (const gchar *name)
if (!fd) if (!fd)
{ {
g_message (_("Could not open '%s' for reading: %s"), g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
gimp_filename_to_utf8 (filename), g_strerror (errno)); _("Could not open '%s' for reading: %s"),
gimp_filename_to_utf8 (filename), g_strerror (errno));
return -1; return -1;
} }
@ -161,8 +166,9 @@ ReadBMP (const gchar *name)
!strncmp (magick, "PI", 2) || !strncmp (magick, "CI", 2) || !strncmp (magick, "PI", 2) || !strncmp (magick, "CI", 2) ||
!strncmp (magick, "CP", 2))) !strncmp (magick, "CP", 2)))
{ {
g_message (_("'%s' is not a valid BMP file"), g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
gimp_filename_to_utf8 (filename)); _("'%s' is not a valid BMP file"),
gimp_filename_to_utf8 (filename));
return -1; return -1;
} }
@ -170,22 +176,25 @@ ReadBMP (const gchar *name)
{ {
if (!ReadOK (fd, buffer, 12)) if (!ReadOK (fd, buffer, 12))
{ {
g_message (_("'%s' is not a valid BMP file"), g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
gimp_filename_to_utf8 (filename)); _("'%s' is not a valid BMP file"),
gimp_filename_to_utf8 (filename));
return -1; return -1;
} }
if (!ReadOK (fd, magick, 2)) if (!ReadOK (fd, magick, 2))
{ {
g_message (_("'%s' is not a valid BMP file"), g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
gimp_filename_to_utf8 (filename)); _("'%s' is not a valid BMP file"),
gimp_filename_to_utf8 (filename));
return -1; return -1;
} }
} }
if (!ReadOK (fd, buffer, 12)) if (!ReadOK (fd, buffer, 12))
{ {
g_message (_("'%s' is not a valid BMP file"), g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
gimp_filename_to_utf8 (filename)); _("'%s' is not a valid BMP file"),
gimp_filename_to_utf8 (filename));
return -1; return -1;
} }
@ -198,8 +207,9 @@ ReadBMP (const gchar *name)
if (!ReadOK (fd, buffer, 4)) if (!ReadOK (fd, buffer, 4))
{ {
g_message (_("'%s' is not a valid BMP file"), g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
gimp_filename_to_utf8 (filename)); _("'%s' is not a valid BMP file"),
gimp_filename_to_utf8 (filename));
return -1; return -1;
} }
@ -211,8 +221,9 @@ ReadBMP (const gchar *name)
{ {
if (!ReadOK (fd, buffer, 8)) if (!ReadOK (fd, buffer, 8))
{ {
g_message (_("Error reading BMP file header from '%s'"), g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
gimp_filename_to_utf8 (filename)); _("Error reading BMP file header from '%s'"),
gimp_filename_to_utf8 (filename));
return -1; return -1;
} }
@ -237,10 +248,12 @@ ReadBMP (const gchar *name)
{ {
if (!ReadOK (fd, buffer, 36)) if (!ReadOK (fd, buffer, 36))
{ {
g_message (_("Error reading BMP file header from '%s'"), g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
gimp_filename_to_utf8 (filename)); _("Error reading BMP file header from '%s'"),
gimp_filename_to_utf8 (filename));
return -1; return -1;
} }
Bitmap_Head.biWidth = ToL (&buffer[0x00]); /* 12 */ Bitmap_Head.biWidth = ToL (&buffer[0x00]); /* 12 */
Bitmap_Head.biHeight = ToL (&buffer[0x04]); /* 16 */ Bitmap_Head.biHeight = ToL (&buffer[0x04]); /* 16 */
Bitmap_Head.biPlanes = ToS (&buffer[0x08]); /* 1A */ Bitmap_Head.biPlanes = ToS (&buffer[0x08]); /* 1A */
@ -260,22 +273,24 @@ ReadBMP (const gchar *name)
memset(masks, 0, sizeof(masks)); memset(masks, 0, sizeof(masks));
if (Bitmap_Head.biCompr == BI_BITFIELDS) if (Bitmap_Head.biCompr == BI_BITFIELDS)
{ {
if (!ReadOK (fd, buffer, 3 * sizeof (guint32))) if (!ReadOK (fd, buffer, 3 * sizeof (guint32)))
{ {
g_message (_("Error reading BMP file header from '%s'"), g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
gimp_filename_to_utf8 (filename)); _("Error reading BMP file header from '%s'"),
return -1; gimp_filename_to_utf8 (filename));
} return -1;
Bitmap_Head.masks[0] = ToL(&buffer[0x00]); }
Bitmap_Head.masks[1] = ToL(&buffer[0x04]);
Bitmap_Head.masks[2] = ToL(&buffer[0x08]); Bitmap_Head.masks[0] = ToL(&buffer[0x00]);
Bitmap_Head.masks[1] = ToL(&buffer[0x04]);
Bitmap_Head.masks[2] = ToL(&buffer[0x08]);
ReadChannelMasks (&Bitmap_Head.masks[0], masks, 3); ReadChannelMasks (&Bitmap_Head.masks[0], masks, 3);
} }
else else
switch (Bitmap_Head.biBitCnt) switch (Bitmap_Head.biBitCnt)
{ {
case 32: case 32:
masks[0].mask = 0x00ff0000; masks[0].mask = 0x00ff0000;
masks[0].shiftin = 16; masks[0].shiftin = 16;
masks[0].max_value= (gfloat)255.0; masks[0].max_value= (gfloat)255.0;
@ -326,10 +341,12 @@ ReadBMP (const gchar *name)
{ {
if (!ReadOK (fd, buffer, Bitmap_File_Head.biSize - 4)) if (!ReadOK (fd, buffer, Bitmap_File_Head.biSize - 4))
{ {
g_message (_("Error reading BMP file header from '%s'"), g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
gimp_filename_to_utf8 (filename)); _("Error reading BMP file header from '%s'"),
gimp_filename_to_utf8 (filename));
return -1; return -1;
} }
Bitmap_Head.biWidth =ToL (&buffer[0x00]); /* 12 */ Bitmap_Head.biWidth =ToL (&buffer[0x00]); /* 12 */
Bitmap_Head.biHeight =ToL (&buffer[0x04]); /* 16 */ Bitmap_Head.biHeight =ToL (&buffer[0x04]); /* 16 */
Bitmap_Head.biPlanes =ToS (&buffer[0x08]); /* 1A */ Bitmap_Head.biPlanes =ToS (&buffer[0x08]); /* 1A */
@ -350,8 +367,9 @@ ReadBMP (const gchar *name)
} }
else else
{ {
g_message (_("Error reading BMP file header from '%s'"), g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
gimp_filename_to_utf8 (filename)); _("Error reading BMP file header from '%s'"),
gimp_filename_to_utf8 (filename));
return -1; return -1;
} }
@ -371,30 +389,37 @@ ReadBMP (const gchar *name)
/* Sanity checks */ /* Sanity checks */
if (Bitmap_Head.biHeight == 0 || Bitmap_Head.biWidth == 0) { if (Bitmap_Head.biHeight == 0 || Bitmap_Head.biWidth == 0)
g_message (_("Error reading BMP file header from '%s'"),
gimp_filename_to_utf8 (filename));
return -1;
}
if (Bitmap_Head.biWidth < 0)
{ {
g_message (_("'%s' is not a valid BMP file"), g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
gimp_filename_to_utf8 (filename)); _("'%s' is not a valid BMP file"),
gimp_filename_to_utf8 (filename));
return -1; return -1;
} }
if (Bitmap_Head.biPlanes != 1) { if (Bitmap_Head.biWidth < 0)
g_message (_("Error reading BMP file header from '%s'"), {
gimp_filename_to_utf8 (filename)); g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
_("'%s' is not a valid BMP file"),
gimp_filename_to_utf8 (filename));
return -1; return -1;
} }
if (Bitmap_Head.biClrUsed > 256) { if (Bitmap_Head.biPlanes != 1)
g_message (_("Error reading BMP file header from '%s'"), {
gimp_filename_to_utf8 (filename)); g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
_("'%s' is not a valid BMP file"),
gimp_filename_to_utf8 (filename));
return -1; return -1;
} }
if (Bitmap_Head.biClrUsed > 256)
{
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
_("'%s' is not a valid BMP file"),
gimp_filename_to_utf8 (filename));
return -1;
}
/* Windows and OS/2 declare filler so that rows are a multiple of /* Windows and OS/2 declare filler so that rows are a multiple of
* word length (32 bits == 4 bytes) * word length (32 bits == 4 bytes)
@ -436,7 +461,8 @@ ReadBMP (const gchar *name)
Bitmap_Head.biCompr, Bitmap_Head.biCompr,
rowbytes, rowbytes,
Grey, Grey,
masks); masks,
error);
if (image_ID < 0) if (image_ID < 0)
return -1; return -1;
@ -465,16 +491,17 @@ ReadBMP (const gchar *name)
} }
static gint32 static gint32
ReadImage (FILE *fd, ReadImage (FILE *fd,
gint width, gint width,
gint height, gint height,
guchar cmap[256][3], guchar cmap[256][3],
gint ncols, gint ncols,
gint bpp, gint bpp,
gint compression, gint compression,
gint rowbytes, gint rowbytes,
gboolean grey, gboolean grey,
const Bitmap_Channel *masks) const Bitmap_Channel *masks,
GError **error)
{ {
guchar v, n; guchar v, n;
GimpPixelRgn pixel_rgn; GimpPixelRgn pixel_rgn;
@ -499,7 +526,9 @@ ReadImage (FILE *fd,
(bpp == 16 && compression == BI_BITFIELDS) || (bpp == 16 && compression == BI_BITFIELDS) ||
(bpp == 32 && compression == BI_BITFIELDS))) (bpp == 32 && compression == BI_BITFIELDS)))
{ {
g_message (_("Unrecognized or invalid BMP compression format.")); g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
"%s",
_("Unrecognized or invalid BMP compression format."));
return -1; return -1;
} }
@ -550,11 +579,13 @@ ReadImage (FILE *fd,
g_message (_("Unsupported or invalid image width: %d"), width); g_message (_("Unsupported or invalid image width: %d"), width);
return -1; return -1;
} }
if ((height < 0) || (height > GIMP_MAX_IMAGE_SIZE)) if ((height < 0) || (height > GIMP_MAX_IMAGE_SIZE))
{ {
g_message (_("Unsupported or invalid image height: %d"), height); g_message (_("Unsupported or invalid image height: %d"), height);
return -1; return -1;
} }
image = gimp_image_new (width, height, base_type); image = gimp_image_new (width, height, base_type);
layer = gimp_layer_new (image, _("Background"), layer = gimp_layer_new (image, _("Background"),
width, height, width, height,

View File

@ -138,9 +138,10 @@ warning_dialog (const gchar *primary,
} }
GimpPDBStatusType GimpPDBStatusType
WriteBMP (const gchar *filename, WriteBMP (const gchar *filename,
gint32 image, gint32 image,
gint32 drawable_ID) gint32 drawable_ID,
GError **error)
{ {
FILE *outfile; FILE *outfile;
gint Red[MAXCOLORS]; gint Red[MAXCOLORS];
@ -291,8 +292,9 @@ WriteBMP (const gchar *filename,
outfile = g_fopen (filename, "wb"); outfile = g_fopen (filename, "wb");
if (!outfile) if (!outfile)
{ {
g_message (_("Could not open '%s' for writing: %s"), g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
gimp_filename_to_utf8 (filename), g_strerror (errno)); _("Could not open '%s' for writing: %s"),
gimp_filename_to_utf8 (filename), g_strerror (errno));
return GIMP_PDB_EXECUTION_ERROR; return GIMP_PDB_EXECUTION_ERROR;
} }

View File

@ -157,12 +157,13 @@ run (const gchar *name,
gint *nreturn_vals, gint *nreturn_vals,
GimpParam **return_vals) GimpParam **return_vals)
{ {
static GimpParam values[2]; static GimpParam values[2];
GimpRunMode run_mode; GimpRunMode run_mode;
GimpPDBStatusType status = GIMP_PDB_SUCCESS; GimpPDBStatusType status = GIMP_PDB_SUCCESS;
gint32 image_ID; gint32 image_ID;
gint32 drawable_ID; gint32 drawable_ID;
GimpExportReturn export = GIMP_EXPORT_CANCEL; GimpExportReturn export = GIMP_EXPORT_CANCEL;
GError *error = NULL;
run_mode = param[0].data.d_int32; run_mode = param[0].data.d_int32;
@ -193,7 +194,7 @@ run (const gchar *name,
if (status == GIMP_PDB_SUCCESS) if (status == GIMP_PDB_SUCCESS)
{ {
image_ID = ReadBMP (param[1].data.d_string); image_ID = ReadBMP (param[1].data.d_string, &error);
if (image_ID != -1) if (image_ID != -1)
{ {
@ -246,7 +247,8 @@ run (const gchar *name,
} }
if (status == GIMP_PDB_SUCCESS) if (status == GIMP_PDB_SUCCESS)
status = WriteBMP (param[3].data.d_string, image_ID, drawable_ID); status = WriteBMP (param[3].data.d_string, image_ID, drawable_ID,
&error);
if (export == GIMP_EXPORT_EXPORT) if (export == GIMP_EXPORT_EXPORT)
gimp_image_delete (image_ID); gimp_image_delete (image_ID);
@ -256,5 +258,12 @@ run (const gchar *name,
status = GIMP_PDB_CALLING_ERROR; status = GIMP_PDB_CALLING_ERROR;
} }
if (status != GIMP_PDB_SUCCESS && error)
{
*nreturn_vals = 2;
values[1].type = GIMP_PDB_STRING;
values[1].data.d_string = error->message;
}
values[0].data.d_status = status; values[0].data.d_status = status;
} }

View File

@ -32,10 +32,14 @@
#define Write(file,buffer,len) fwrite(buffer, len, 1, file) #define Write(file,buffer,len) fwrite(buffer, len, 1, file)
#define WriteOK(file,buffer,len) (Write(buffer, len, file) != 0) #define WriteOK(file,buffer,len) (Write(buffer, len, file) != 0)
gint32 ReadBMP (const gchar *filename);
GimpPDBStatusType WriteBMP (const gchar *filename, gint32 ReadBMP (const gchar *filename,
gint32 image, GError **error);
gint32 drawable_ID); GimpPDBStatusType WriteBMP (const gchar *filename,
gint32 image,
gint32 drawable_ID,
GError **error);
extern gboolean interactive; extern gboolean interactive;
extern gboolean lastvals; extern gboolean lastvals;