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> 2003-05-15 Michael Natterer <mitch@gimp.org>
* app/xcf/xcf-save.c: cleaned up the old path saving functions * app/xcf/xcf-save.c: cleaned up the old path saving functions

View File

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

View File

@ -591,92 +591,3 @@ file_check_magic_list (GSList *magics_list,
return 0; 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); 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__ */ #endif /* __FILE_UTILS_H__ */

View File

@ -41,6 +41,7 @@
#include "pdb-types.h" #include "pdb-types.h"
#include "procedural_db.h" #include "procedural_db.h"
#include "base/temp-buf.h"
#include "config/gimpbaseconfig.h" #include "config/gimpbaseconfig.h"
#include "config/gimpconfig-path.h" #include "config/gimpconfig-path.h"
#include "core/gimp.h" #include "core/gimp.h"
@ -224,12 +225,9 @@ file_load_thumbnail_invoker (Gimp *gimp,
gint32 height = 0; gint32 height = 0;
gint32 num_bytes = 0; gint32 num_bytes = 0;
guint8 *thumb_data = NULL; guint8 *thumb_data = NULL;
gchar *pname; gchar *uri;
gchar *fname; GimpImagefile *imagefile = NULL;
gchar *tname; TempBuf *temp_buf = NULL;
guchar *raw_thumb;
gchar *imginfo = NULL;
gint i;
filename = (gchar *) args[0].value.pdb_pointer; filename = (gchar *) args[0].value.pdb_pointer;
if (filename == NULL) if (filename == NULL)
@ -237,30 +235,43 @@ file_load_thumbnail_invoker (Gimp *gimp,
if (success) if (success)
{ {
pname = g_path_get_dirname (filename); uri = g_filename_to_uri (filename, NULL, NULL);
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);
if (raw_thumb) if (uri)
imagefile = gimp_imagefile_new (gimp, uri);
if (imagefile)
{ {
num_bytes = 3 * width * height; temp_buf = gimp_viewable_get_preview (GIMP_VIEWABLE (imagefile),
thumb_data = g_malloc (num_bytes); GIMP_THUMBNAIL_SIZE_NORMAL,
GIMP_THUMBNAIL_SIZE_NORMAL);
for (i=0; i<width*height; i++) g_object_unref (imagefile);
{ }
thumb_data[i*3 ] = ((raw_thumb[i]>>5)*255)/7;
thumb_data[i*3+1] = (((raw_thumb[i]>>2)&7)*255)/7; if (temp_buf && temp_buf->bytes != 3)
thumb_data[i*3+2] = (((raw_thumb[i])&3)*255)/3; {
} g_warning ("FIXME: handle thumbnails with bpp != 3");
g_free (raw_thumb);
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; success = TRUE;
} }
else else
success = FALSE; {
success = FALSE;
}
g_free (uri);
} }
return_args = procedural_db_return_args (&file_load_thumbnail_proc, success); 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.", "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",
"Adam D. Moss, Sven Neumann", "Adam D. Moss, Sven Neumann",
"1999-2000", "1999-2003",
GIMP_INTERNAL, GIMP_INTERNAL,
1, 1,
file_load_thumbnail_inargs, file_load_thumbnail_inargs,

View File

@ -49,7 +49,8 @@
; merge all visible layers ; merge all visible layers
(if (> num-visi-layers 1) (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) (if (> num-visi-layers 0)
(set! merged-layer copy))) (set! merged-layer copy)))
@ -72,10 +73,10 @@
(script-fu-register "script-fu-copy-visible" (script-fu-register "script-fu-copy-visible"
_"<Image>/Edit/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 <sven@gimp.org>, Adrian Likins <adrian@gimp.org>"
"Sven Neumann, Adrian Likins" "Sven Neumann, Adrian Likins"
"01/24/1998" "01/24/1998"
"RGB* INDEXED* GRAY*" "RGB* INDEXED* GRAY*"
SF-IMAGE "Image" 0 SF-IMAGE "Image" 0
SF-DRAWABLE "Drawable" 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> 2003-05-12 Jan Morén <jan.moren@lucs.lu.se>
* sv.po: Updated Swedish translation. * sv.po: Updated Swedish translation.

View File

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

View File

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