added some sanity checks to temp_buf conversion routines.

2003-05-15  Sven Neumann  <sven@gimp.org>

	* app/base/temp-buf.c: added some sanity checks to temp_buf
	conversion routines.

	* tools/pdbgen/pdb/fileops.pdb (file_load_thumbnail_invoker): use
	GimpImagefile to load a thumbnail. Only works for RGB images yet.
	This adresses bug #113033.

	* app/pdb/fileops_cmds.c: regenerated.

	* app/file/file-utils.[ch]: removed file_utils_readXVThumb(). It
	is not needed any longer since GimpImagefile also handles the
	old-style .xvpics.

	* plug-ins/script-fu/scripts/copy-visible.scm: fixed typo.
This commit is contained in:
Sven Neumann 2003-05-15 13:33:30 +00:00 committed by Sven Neumann
parent 71a578fc30
commit 929fef0d57
9 changed files with 185 additions and 211 deletions

View File

@ -1,3 +1,20 @@
2003-05-15 Sven Neumann <sven@gimp.org>
* app/base/temp-buf.c: added some sanity checks to temp_buf
conversion routines.
* tools/pdbgen/pdb/fileops.pdb (file_load_thumbnail_invoker): use
GimpImagefile to load a thumbnail. Only works for RGB images yet.
This adresses bug #113033.
* app/pdb/fileops_cmds.c: regenerated.
* app/file/file-utils.[ch]: removed file_utils_readXVThumb(). It
is not needed any longer since GimpImagefile also handles the
old-style .xvpics.
* plug-ins/script-fu/scripts/copy-visible.scm: fixed typo.
2003-05-15 Michael Natterer <mitch@gimp.org>
* app/xcf/xcf-save.c: cleaned up the old path saving functions

View File

@ -45,7 +45,7 @@
#include "paint-funcs/paint-funcs.h"
static guchar * temp_buf_allocate (guint);
static guchar * temp_buf_allocate (guint size);
static void temp_buf_to_color (TempBuf *src_buf,
TempBuf *dest_buf);
static void temp_buf_to_gray (TempBuf *src_buf,
@ -63,11 +63,7 @@ extern GimpBaseConfig *base_config;
static guchar *
temp_buf_allocate (guint size)
{
guchar *data;
data = g_new (guchar, size);
return data;
return g_new (guchar, size);
}
@ -86,8 +82,21 @@ temp_buf_to_color (TempBuf *src_buf,
num_pixels = src_buf->width * src_buf->height;
if (dest_buf->bytes == 4)
switch (dest_buf->bytes)
{
case 3:
g_return_if_fail (src_buf->bytes != 1);
while (num_pixels--)
{
guchar tmpch;
*dest++ = tmpch = *src++;
*dest++ = tmpch;
*dest++ = tmpch;
}
break;
case 4:
g_return_if_fail (src_buf->bytes != 2);
while (num_pixels--)
{
guchar tmpch;
@ -97,16 +106,11 @@ temp_buf_to_color (TempBuf *src_buf,
*dest++ = *src++; /* alpha channel */
}
}
else
{
while (num_pixels--)
{
guchar tmpch;
*dest++ = tmpch = *src++;
*dest++ = tmpch;
*dest++ = tmpch;
}
break;
default:
g_return_if_reached ();
break;
}
}
@ -124,8 +128,21 @@ temp_buf_to_gray (TempBuf *src_buf,
num_pixels = src_buf->width * src_buf->height;
if (dest_buf->bytes == 2)
switch (dest_buf->bytes)
{
case 1:
g_return_if_fail (src_buf->bytes != 3);
while (num_pixels--)
{
pix = INTENSITY (src[0], src[1], src[2]);
*dest++ = (guchar) pix;
src += 3;
}
break;
case 2:
g_return_if_fail (src_buf->bytes != 4);
while (num_pixels--)
{
pix = INTENSITY (src[0], src[1], src[2]);
@ -135,16 +152,11 @@ temp_buf_to_gray (TempBuf *src_buf,
src += 4;
}
}
else
{
while (num_pixels--)
{
pix = INTENSITY (src[0], src[1], src[2]);
*dest++ = (guchar) pix;
break;
src += 3;
}
default:
g_return_if_reached ();
break;
}
}
@ -315,13 +327,13 @@ temp_buf_copy (TempBuf *src,
if (src->bytes != dest->bytes)
{
if (src->bytes == 4 && dest->bytes == 2) /* RGBA -> GRAYA */
if (src->bytes == 4 && dest->bytes == 2) /* RGBA -> GRAYA */
temp_buf_to_gray (src, dest);
else if (src->bytes == 3 && dest->bytes == 1) /* RGB -> GRAY */
else if (src->bytes == 3 && dest->bytes == 1) /* RGB -> GRAY */
temp_buf_to_gray (src, dest);
else if (src->bytes == 2 && dest->bytes == 4) /* GRAYA -> RGBA */
else if (src->bytes == 2 && dest->bytes == 4) /* GRAYA -> RGBA */
temp_buf_to_color (src, dest);
else if (src->bytes == 1 && dest->bytes == 3) /* GRAYA -> RGBA */
else if (src->bytes == 1 && dest->bytes == 3) /* GRAY -> RGB */
temp_buf_to_color (src, dest);
else
g_warning ("temp_buf_copy(): unimplemented color conversion");
@ -697,12 +709,17 @@ temp_buf_swap (TempBuf *buf)
/* Open file for overwrite */
if ((fp = fopen (filename, "wb")))
{
size_t blocks_written;
blocks_written = fwrite (swap->data, swap->width * swap->height * swap->bytes, 1, fp);
/* Check whether all bytes were written and fclose() was able to flush its buffers */
gsize blocks_written;
blocks_written = fwrite (swap->data,
swap->width * swap->height * swap->bytes, 1,
fp);
/* Check whether all bytes were written and fclose() was able
to flush its buffers */
if ((0 != fclose (fp)) || (1 != blocks_written))
{
(void) unlink (filename);
unlink (filename);
perror ("Write error on temp buf");
g_message ("Cannot write \"%s\"", filename);
g_free (filename);
@ -711,7 +728,7 @@ temp_buf_swap (TempBuf *buf)
}
else
{
(void) unlink (filename);
unlink (filename);
perror ("Error in temp buf caching");
g_message ("Cannot write \"%s\"", filename);
g_free (filename);
@ -750,9 +767,13 @@ temp_buf_unswap (TempBuf *buf)
{
if ((fp = fopen (buf->filename, "rb")))
{
size_t blocks_read;
blocks_read = fread (buf->data, buf->width * buf->height * buf->bytes, 1, fp);
(void) fclose (fp);
gsize blocks_read;
blocks_read = fread (buf->data,
buf->width * buf->height * buf->bytes, 1,
fp);
fclose (fp);
if (blocks_read != 1)
perror ("Read error on temp buf");
else
@ -764,8 +785,10 @@ temp_buf_unswap (TempBuf *buf)
/* Delete the swap file */
unlink (buf->filename);
}
if (!succ)
g_message ("Error in temp buf caching: information swapped to disk was lost!");
g_message ("Error in temp buf caching: "
"information swapped to disk was lost!");
g_free (buf->filename); /* free filename */
buf->filename = NULL;
@ -794,7 +817,8 @@ temp_buf_swap_free (TempBuf *buf)
unlink (buf->filename);
}
else
g_message ("Error in temp buf disk swapping: information swapped to disk was lost!");
g_message ("Error in temp buf disk swapping: "
"information swapped to disk was lost!");
if (buf->filename)
g_free (buf->filename); /* free filename */

View File

@ -591,92 +591,3 @@ file_check_magic_list (GSList *magics_list,
return 0;
}
/* The readXVThumb function source may be re-used under
* the XFree86-style license. <adam@gimp.org>
*/
guchar *
file_utils_readXVThumb (const gchar *fnam,
gint *w,
gint *h,
gchar **imginfo /* caller frees if != NULL */)
{
FILE *fp;
const gchar *P7_332 = "P7 332";
gchar P7_buf[7];
gchar linebuf[200];
guchar *buf;
gint twofivefive;
void *ptr;
*w = *h = 0;
*imginfo = NULL;
fp = fopen (fnam, "rb");
if (!fp)
return NULL;
fread (P7_buf, 6, 1, fp);
if (strncmp (P7_buf, P7_332, 6)!=0)
{
g_warning ("Thumbnail does not have the 'P7 332' header.");
fclose (fp);
return NULL;
}
/*newline*/
fread (P7_buf, 1, 1, fp);
do
{
ptr = fgets (linebuf, 199, fp);
if ((strncmp (linebuf, "#IMGINFO:", 9) == 0) &&
(linebuf[9] != '\0') &&
(linebuf[9] != '\n'))
{
if (linebuf[strlen(linebuf)-1] == '\n')
linebuf[strlen(linebuf)-1] = '\0';
if (linebuf[9] != '\0')
{
if (*imginfo)
g_free (*imginfo);
*imginfo = g_strdup (&linebuf[9]);
}
}
}
while (ptr && linebuf[0]=='#'); /* keep throwing away comment lines */
if (!ptr)
{
/* g_warning("Thumbnail ended - not an image?"); */
fclose (fp);
return NULL;
}
sscanf (linebuf, "%d %d %d\n", w, h, &twofivefive);
if (twofivefive!=255)
{
g_warning ("Thumbnail depth is incorrect.");
fclose (fp);
return NULL;
}
if ((*w)<1 || (*h)<1 || (*w)>80 || (*h)>60)
{
g_warning ("Thumbnail size is bad. Corrupted?");
fclose (fp);
return NULL;
}
buf = g_malloc ((*w) * (*h));
fread (buf, (*w) * (*h), 1, fp);
fclose (fp);
return buf;
}

View File

@ -32,12 +32,4 @@ gchar * file_utils_uri_to_utf8_basename (const gchar *uri);
gchar * file_utils_uri_to_utf8_filename (const gchar *uri);
/* .xvpics thumbnail stuff */
guchar * file_utils_readXVThumb (const gchar *fnam,
gint *w,
gint *h,
gchar **imginfo /* caller frees if != NULL */);
#endif /* __FILE_UTILS_H__ */

View File

@ -41,6 +41,7 @@
#include "pdb-types.h"
#include "procedural_db.h"
#include "base/temp-buf.h"
#include "config/gimpbaseconfig.h"
#include "config/gimpconfig-path.h"
#include "core/gimp.h"
@ -224,12 +225,9 @@ file_load_thumbnail_invoker (Gimp *gimp,
gint32 height = 0;
gint32 num_bytes = 0;
guint8 *thumb_data = NULL;
gchar *pname;
gchar *fname;
gchar *tname;
guchar *raw_thumb;
gchar *imginfo = NULL;
gint i;
gchar *uri;
GimpImagefile *imagefile = NULL;
TempBuf *temp_buf = NULL;
filename = (gchar *) args[0].value.pdb_pointer;
if (filename == NULL)
@ -237,30 +235,43 @@ file_load_thumbnail_invoker (Gimp *gimp,
if (success)
{
pname = g_path_get_dirname (filename);
fname = g_path_get_basename (filename);
tname = g_build_filename (pname, ".xvpics", fname, NULL);
g_free (pname);
g_free (fname);
raw_thumb = file_utils_readXVThumb (tname, &width, &height, &imginfo);
g_free (tname);
uri = g_filename_to_uri (filename, NULL, NULL);
if (raw_thumb)
if (uri)
imagefile = gimp_imagefile_new (gimp, uri);
if (imagefile)
{
num_bytes = 3 * width * height;
thumb_data = g_malloc (num_bytes);
for (i=0; i<width*height; i++)
{
thumb_data[i*3 ] = ((raw_thumb[i]>>5)*255)/7;
thumb_data[i*3+1] = (((raw_thumb[i]>>2)&7)*255)/7;
thumb_data[i*3+2] = (((raw_thumb[i])&3)*255)/3;
}
g_free (raw_thumb);
temp_buf = gimp_viewable_get_preview (GIMP_VIEWABLE (imagefile),
GIMP_THUMBNAIL_SIZE_NORMAL,
GIMP_THUMBNAIL_SIZE_NORMAL);
g_object_unref (imagefile);
}
if (temp_buf && temp_buf->bytes != 3)
{
g_warning ("FIXME: handle thumbnails with bpp != 3");
temp_buf_free (temp_buf);
temp_buf = NULL;
}
if (temp_buf)
{
width = temp_buf->width;
height = temp_buf->height;
num_bytes = 3 * width * height;
thumb_data = g_memdup (temp_buf_data (temp_buf), num_bytes);
temp_buf_free (temp_buf);
success = TRUE;
}
else
success = FALSE;
{
success = FALSE;
}
g_free (uri);
}
return_args = procedural_db_return_args (&file_load_thumbnail_proc, success);
@ -316,7 +327,7 @@ static ProcRecord file_load_thumbnail_proc =
"This procedure tries to load a thumbnail that belongs to the file with the given filename. This name is a full pathname. The returned data is an array of colordepth 3 (RGB), regardless of the image type. Width and height of the thumbnail are also returned. Don't use this function if you need a thumbnail of an already opened image, use gimp_image_thumbnail instead.",
"Adam D. Moss, Sven Neumann",
"Adam D. Moss, Sven Neumann",
"1999-2000",
"1999-2003",
GIMP_INTERNAL,
1,
file_load_thumbnail_inargs,

View File

@ -49,7 +49,8 @@
; merge all visible layers
(if (> num-visi-layers 1)
(set! merged-layer (car (gimp-image-merge-visible-layers image EXPAND-AS-NECESSARY)))
(set! merged-layer (car (gimp-image-merge-visible-layers image
EXPAND-AS-NECESSARY)))
(if (> num-visi-layers 0)
(set! merged-layer copy)))
@ -72,10 +73,10 @@
(script-fu-register "script-fu-copy-visible"
_"<Image>/Edit/Copy Visible"
"Copy the visible selction"
"Copy the visible selection"
"Sven Neumann <sven@gimp.org>, Adrian Likins <adrian@gimp.org>"
"Sven Neumann, Adrian Likins"
"01/24/1998"
"RGB* INDEXED* GRAY*"
SF-IMAGE "Image" 0
SF-IMAGE "Image" 0
SF-DRAWABLE "Drawable" 0)

View File

@ -1,3 +1,7 @@
2003-05-15 Sven Neumann <sven@gimp.org>
* Makefile.in.in: updated.
2003-05-12 Jan Morén <jan.moren@lucs.lu.se>
* sv.po: Updated Swedish translation.

View File

@ -75,7 +75,7 @@ INSTOBJEXT = @INSTOBJEXT@
.po.pox:
$(MAKE) $(GETTEXT_PACKAGE).pot
$(MSGMERGE) $< $(srcdir)/$(GETTEXT_PACKAGE).pot -o $*.pox
$(MSGMERGE) $< $(srcdir)/$(GETTEXT_PACKAGE).pot -o $*pox
.po.mo:
$(MSGFMT) -o $@ $<
@ -168,7 +168,9 @@ uninstall:
rm -f $(DESTDIR)$(gnulocaledir)/$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE)$(INSTOBJEXT); \
rm -f $(DESTDIR)$(gnulocaledir)/$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE)$(INSTOBJEXT).m; \
done
rm -f $(DESTDIR)$(gettextsrcdir)/po-Makefile.in.in
if test "$(PACKAGE)" = "glib"; then \
rm -f $(DESTDIR)$(gettextsrcdir)/Makefile.in.in; \
fi
check: all
@ -177,6 +179,7 @@ dvi info tags TAGS ID:
mostlyclean:
rm -f core core.* *.pox $(GETTEXT_PACKAGE).po *.old.po cat-id-tbl.tmp
rm -fr *.o
rm -f .intltool-merge-cache
clean: mostlyclean
@ -198,35 +201,31 @@ dist distdir: update-po $(DISTFILES)
update-po: Makefile
$(MAKE) $(GETTEXT_PACKAGE).pot
tmpdir=`pwd`; \
cd $(srcdir); \
catalogs='$(CATALOGS)'; \
for cat in $$catalogs; do \
cat=`basename $$cat`; \
lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \
cp $$lang.po $$lang.old.po; \
echo "$$lang:"; \
if $(MSGMERGE) $$lang; then \
rm -f $$lang.old.po; \
if $$tmpdir/$(INTLTOOL_UPDATE) --gettext-package $(GETTEXT_PACKAGE) --dist -o $$tmpdir/$$lang.new.po $$lang; then \
if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \
rm -f $$tmpdir/$$lang.new.po; \
else \
if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \
:; \
else \
echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \
rm -f $$tmpdir/$$lang.new.po; \
exit 1; \
fi; \
fi; \
else \
echo "msgmerge for $$cat failed!"; \
rm -f $$lang.po; \
mv $$lang.old.po $$lang.po; \
rm -f $$tmpdir/$$lang.new.po; \
fi; \
done
.po: Makefile
$(MAKE) $(PACKAGE).pot;
PATH=`pwd`/../src:$$PATH; \
echo; printf "$*: "; \
if $(MSGMERGE) $*; then \
rm -f $*.old.po; \
else \
echo "msgmerge for * failed!"; \
mv $*.old.po $*.po; \
fi; \
msgfmt --statistics $*.po; echo;
# POTFILES is created from POTFILES.in by stripping comments, empty lines
# and Intltool tags (enclosed in square brackets), and appending a full
# relative path to them

View File

@ -169,7 +169,7 @@ instead.
HELP
$author = $copyright = 'Adam D. Moss, Sven Neumann';
$date = '1999-2000';
$date = '1999-2003';
@inargs = (
{ name => 'filename', type => 'string',
@ -189,34 +189,48 @@ HELP
);
%invoke = (
vars => [ 'gchar *pname', 'gchar *fname', 'gchar *tname',
'guchar *raw_thumb', 'gchar *imginfo = NULL', 'gint i' ],
code => <<'CODE'
vars => [ 'gchar *uri',
'GimpImagefile *imagefile = NULL',
'TempBuf *temp_buf = NULL' ],
code => <<'CODE'
{
pname = g_path_get_dirname (filename);
fname = g_path_get_basename (filename);
tname = g_build_filename (pname, ".xvpics", fname, NULL);
g_free (pname);
g_free (fname);
raw_thumb = file_utils_readXVThumb (tname, &width, &height, &imginfo);
g_free (tname);
uri = g_filename_to_uri (filename, NULL, NULL);
if (raw_thumb)
if (uri)
imagefile = gimp_imagefile_new (gimp, uri);
if (imagefile)
{
num_bytes = 3 * width * height;
thumb_data = g_malloc (num_bytes);
for (i=0; i<width*height; i++)
{
thumb_data[i*3 ] = ((raw_thumb[i]>>5)*255)/7;
thumb_data[i*3+1] = (((raw_thumb[i]>>2)&7)*255)/7;
thumb_data[i*3+2] = (((raw_thumb[i])&3)*255)/3;
}
g_free (raw_thumb);
temp_buf = gimp_viewable_get_preview (GIMP_VIEWABLE (imagefile),
GIMP_THUMBNAIL_SIZE_NORMAL,
GIMP_THUMBNAIL_SIZE_NORMAL);
g_object_unref (imagefile);
}
if (temp_buf && temp_buf->bytes != 3)
{
g_warning ("FIXME: handle thumbnails with bpp != 3");
temp_buf_free (temp_buf);
temp_buf = NULL;
}
if (temp_buf)
{
width = temp_buf->width;
height = temp_buf->height;
num_bytes = 3 * width * height;
thumb_data = g_memdup (temp_buf_data (temp_buf), num_bytes);
temp_buf_free (temp_buf);
success = TRUE;
}
else
success = FALSE;
{
success = FALSE;
}
g_free (uri);
}
CODE
);
@ -445,7 +459,8 @@ CODE
);
}
@headers = qw(<sys/types.h> <unistd.h> "core/gimp.h" "core/gimpimagefile.h"
@headers = qw(<sys/types.h> <unistd.h> "base/temp-buf.h"
"core/gimp.h" "core/gimpimagefile.h"
"plug-in/plug-in.h" "plug-in/plug-ins.h" "plug-in/plug-in-proc.h"
"file/file-utils.h");