[Rawstudio-commit] r2021 - trunk/src

Anders Brander anders at brander.dk
Mon Sep 22 07:58:06 CEST 2008


Author: abrander
Date: 2008-09-22 07:58:06 +0200 (Mon, 22 Sep 2008)
New Revision: 2021

Added:
   trunk/src/rs-filetypes.c
   trunk/src/rs-filetypes.h
Modified:
   trunk/src/Makefile.am
   trunk/src/gtk-interface.c
   trunk/src/rawstudio.c
   trunk/src/rawstudio.h
   trunk/src/rs-actions.c
   trunk/src/rs-batch.c
   trunk/src/rs-metadata.c
   trunk/src/rs-photo.c
   trunk/src/rs-store.c
Log:
Added RSFiletype handler - and ported all image and metadata loaders.

Modified: trunk/src/Makefile.am
===================================================================
--- trunk/src/Makefile.am	2008-09-17 21:29:52 UTC (rev 2020)
+++ trunk/src/Makefile.am	2008-09-22 05:58:06 UTC (rev 2021)
@@ -25,6 +25,7 @@
 
 rawstudio_SOURCES = \
 	rawstudio.c rawstudio.h \
+	rs-filetypes.c rs-filetypes.h \
 	rs-utils.c rs-utils.h \
 	rs-job.c rs-job.h \
 	rs-actions.c rs-actions.h \

Modified: trunk/src/gtk-interface.c
===================================================================
--- trunk/src/gtk-interface.c	2008-09-17 21:29:52 UTC (rev 2020)
+++ trunk/src/gtk-interface.c	2008-09-22 05:58:06 UTC (rev 2021)
@@ -155,29 +155,26 @@
 open_photo(RS_BLOB *rs, const gchar *filename)
 {
 	RS_PHOTO *photo;
-	RS_FILETYPE *filetype;
 	extern GtkLabel *infolabel;
 	gchar *label;
 
-	if ((filetype = rs_filetype_get(filename, TRUE)))
+	rs_preview_widget_set_photo(RS_PREVIEW_WIDGET(rs->preview), NULL);
+	photo = rs_photo_load_from_file(filename, FALSE);
+
+	if (photo)
+		rs_photo_close(rs->photo);
+	else
 	{
-		rs_preview_widget_set_photo(RS_PREVIEW_WIDGET(rs->preview), NULL);
-		photo = rs_photo_load_from_file(filename, FALSE);
+		gui_set_busy(FALSE);
+		return FALSE;
+	}
 
-		if (photo)
-			rs_photo_close(rs->photo);
-		else
-		{
-			gui_set_busy(FALSE);
-			return FALSE;
-		}
+	label = rs_metadata_get_short_description(photo->metadata);
+	gtk_label_set_text(infolabel, label);
+	g_free(label);
 
-		label = rs_metadata_get_short_description(photo->metadata);
-		gtk_label_set_text(infolabel, label);
-		g_free(label);
+	rs_set_photo(rs, photo);
 
-		rs_set_photo(rs, photo);
-	}
 	return TRUE;
 }
 

Modified: trunk/src/rawstudio.c
===================================================================
--- trunk/src/rawstudio.c	2008-09-17 21:29:52 UTC (rev 2020)
+++ trunk/src/rawstudio.c	2008-09-22 05:58:06 UTC (rev 2021)
@@ -51,6 +51,7 @@
 #include "rs-math.h"
 #include "rs-exif.h"
 #include "rs-metadata.h"
+#include "rs-filetypes.h"
 
 static void photo_settings_changed(RS_PHOTO *photo, gint mask, RS_BLOB *rs);
 static void photo_spatial_changed(RS_PHOTO *photo, RS_BLOB *rs);
@@ -78,8 +79,6 @@
 	cur->filetype = filetype;
 	cur->ext = ext;
 	cur->description = description;
-	cur->load = load;
-	cur->load_meta = load_meta;
 	cur->save = save;
 	cur->next = NULL;
 	return;
@@ -88,41 +87,45 @@
 static void
 rs_init_filetypes(void)
 {
+
+	rs_filetype_init();
+
+#define REGISTER_FILETYPE(extension, description, load, meta) do { \
+	rs_filetype_register_loader(extension, description, load, 10); \
+	rs_filetype_register_meta_loader(extension, description, meta, 10); \
+} while(0)
+
+	/* Raw file formats */
+	REGISTER_FILETYPE(".cr2", _("Canon CR2"), rs_image16_open_dcraw,  rs_tiff_load_meta);
+	REGISTER_FILETYPE(".crw", _("Canon CIFF"), rs_image16_open_dcraw, rs_ciff_load_meta);
+	REGISTER_FILETYPE(".nef", _("Nikon NEF"), rs_image16_open_dcraw, rs_tiff_load_meta);
+	REGISTER_FILETYPE(".mrw", _("Minolta raw"), rs_image16_open_dcraw, rs_mrw_load_meta);
+	REGISTER_FILETYPE(".tif", _("Canon TIFF"), rs_image16_open_dcraw, rs_tiff_load_meta);
+	REGISTER_FILETYPE(".arw", _("Sony"), rs_image16_open_dcraw, rs_tiff_load_meta);
+	REGISTER_FILETYPE(".sr2", _("Sony"), rs_image16_open_dcraw, rs_tiff_load_meta);
+	REGISTER_FILETYPE(".srf", _("Sony"), rs_image16_open_dcraw, rs_tiff_load_meta);
+	REGISTER_FILETYPE(".kdc", _("Kodak"), rs_image16_open_dcraw, rs_tiff_load_meta);
+	REGISTER_FILETYPE(".dcr", _("Kodak"), rs_image16_open_dcraw, rs_tiff_load_meta);
+	REGISTER_FILETYPE(".x3f", _("Sigma"), rs_image16_open_dcraw, rs_x3f_load_meta);
+	REGISTER_FILETYPE(".orf", _("Olympus"), rs_image16_open_dcraw, rs_tiff_load_meta);
+	REGISTER_FILETYPE(".raw", _("Panasonic raw"), rs_image16_open_dcraw, rs_tiff_load_meta);
+	REGISTER_FILETYPE(".pef", _("Pentax raw"), rs_image16_open_dcraw, rs_tiff_load_meta);
+	REGISTER_FILETYPE(".dng", _("Adobe Digital negative"), rs_image16_open_dcraw, rs_tiff_load_meta);
+	REGISTER_FILETYPE(".mef", _("Mamiya"), rs_image16_open_dcraw, rs_tiff_load_meta);
+	REGISTER_FILETYPE(".3fr", _("Hasselblad"), rs_image16_open_dcraw, rs_tiff_load_meta);
+
+	/* GDK formats */
+	REGISTER_FILETYPE(".jpg", _("JPEG (Joint Photographic Experts Group)"), rs_image16_open_gdk, rs_gdk_load_meta);
+	REGISTER_FILETYPE(".png", _("PNG (Portable Network Graphics)"), rs_image16_open_gdk, rs_gdk_load_meta);
+
+#undef REGISTER_FILETYPE
+
+	/* TIFF is special - we need higher priority to try raw first */
+	rs_filetype_register_loader(".tif", _("8-bit TIFF (Tagged Image File Format)"), rs_image16_open_gdk, 20);
+	rs_filetype_register_meta_loader(".tif", _("8-bit TIFF (Tagged Image File Format)"), rs_gdk_load_meta, 20);
+
+	/* Old-style savers - FIXME: Port to RSFiletype */
 	filetypes = NULL;
-	rs_add_filetype("cr2", FILETYPE_RAW, ".cr2", _("Canon CR2"),
-		rs_image16_open_dcraw,  rs_tiff_load_meta, NULL);
-	rs_add_filetype("crw", FILETYPE_RAW, ".crw", _("Canon CIFF"),
-		rs_image16_open_dcraw,  rs_ciff_load_meta, NULL);
-	rs_add_filetype("nef", FILETYPE_RAW, ".nef", _("Nikon NEF"),
-		rs_image16_open_dcraw,  rs_tiff_load_meta, NULL);
-	rs_add_filetype("mrw", FILETYPE_RAW, ".mrw", _("Minolta raw"),
-		rs_image16_open_dcraw, rs_mrw_load_meta, NULL);
-	rs_add_filetype("cr-tiff", FILETYPE_RAW, ".tif", _("Canon TIFF"),
-		rs_image16_open_dcraw,  rs_tiff_load_meta, NULL);
-	rs_add_filetype("arw", FILETYPE_RAW, ".arw", _("Sony"),
-		rs_image16_open_dcraw,  rs_tiff_load_meta, NULL);
-	rs_add_filetype("sr2", FILETYPE_RAW, ".sr2", _("Sony"),
-		rs_image16_open_dcraw,  rs_tiff_load_meta, NULL);
-	rs_add_filetype("sr2", FILETYPE_RAW, ".srf", _("Sony"),
-		rs_image16_open_dcraw,  rs_tiff_load_meta, NULL);
-	rs_add_filetype("kdc", FILETYPE_RAW, ".kdc", _("Kodak"),
-		rs_image16_open_dcraw,  rs_tiff_load_meta, NULL);
-	rs_add_filetype("kdc", FILETYPE_RAW, ".dcr", _("Kodak"),
-		rs_image16_open_dcraw,  rs_tiff_load_meta, NULL);
-	rs_add_filetype("x3f", FILETYPE_RAW, ".x3f", _("Sigma"),
-		rs_image16_open_dcraw, rs_x3f_load_meta, NULL);
-	rs_add_filetype("orf", FILETYPE_RAW, ".orf", "",
-		rs_image16_open_dcraw,  rs_tiff_load_meta, NULL);
-	rs_add_filetype("raw", FILETYPE_RAW, ".raw", _("Panasonic raw"),
-		rs_image16_open_dcraw,  rs_tiff_load_meta, NULL);
-	rs_add_filetype("pef", FILETYPE_RAW, ".pef", _("Pentax raw"),
-		rs_image16_open_dcraw,  rs_tiff_load_meta, NULL);
-	rs_add_filetype("dng", FILETYPE_RAW, "dng", _("Adobe Digital negative"),
-		rs_image16_open_dcraw,  rs_tiff_load_meta, NULL);
-	rs_add_filetype("mef", FILETYPE_RAW, "mef", _("Mamiya"),
-		rs_image16_open_dcraw,  rs_tiff_load_meta, NULL);
-	rs_add_filetype("3fr", FILETYPE_RAW, "3fr", _("Hasselblad"),
-		rs_image16_open_dcraw,  rs_tiff_load_meta, NULL);
 	rs_add_filetype("jpeg", FILETYPE_JPEG, ".jpg", _("JPEG (Joint Photographic Experts Group)"),
 		rs_image16_open_gdk, rs_gdk_load_meta, rs_photo_save);
 	rs_add_filetype("png", FILETYPE_PNG, ".png", _("PNG (Portable Network Graphics)"),
@@ -545,36 +548,6 @@
 	return(rs);
 }
 
-RS_FILETYPE *
-rs_filetype_get(const gchar *filename, gboolean load)
-{
-	RS_FILETYPE *filetype = filetypes;
-	RS_FILETYPE *ret = NULL;
-	gchar *iname;
-	gint n;
-	gboolean load_gdk = FALSE;
-	rs_conf_get_boolean(CONF_LOAD_GDK, &load_gdk);
-	iname = g_ascii_strdown(filename,-1);
-	n = 0;
-	while(filetype)
-	{
-		if (g_str_has_suffix(iname, filetype->ext))
-		{
-			if ((!load) || (filetype->load))
-			{
-				if (filetype->filetype == FILETYPE_RAW)
-					ret = filetype;
-				else if ((filetype->filetype != FILETYPE_RAW) && (load_gdk))
-					ret = filetype;
-				break;
-			}
-		}
-		filetype = filetype->next;
-	}
-	g_free(iname);
-	return ret;
-}
-
 gchar *
 rs_confdir_get()
 {
@@ -661,44 +634,6 @@
 	metadata->thumbnail = gdk_pixbuf_new_from_file_at_size(src, 128, 128, NULL);
 }
 
-GdkPixbuf *
-rs_load_thumb(RS_FILETYPE *filetype, const gchar *src)
-{
-	GdkPixbuf * pixbuf = NULL;
-	gchar *thumbname = rs_thumb_get_name(src);
-
-	if (thumbname)
-	{
-		pixbuf = gdk_pixbuf_new_from_file(thumbname, NULL);
-
-		if (!pixbuf)
-		{
-			RSMetadata *metadata = rs_metadata_new_from_file(src);
-			pixbuf = metadata->thumbnail;
-
-			if (pixbuf)
-			{
-				g_object_ref(pixbuf);
-				gdk_pixbuf_save(pixbuf, thumbname, "png", NULL, NULL);
-			}
-			g_object_unref(metadata);
-		}
-
-		g_free(thumbname);
-	}
-	else
-	{
-		RSMetadata *metadata = rs_metadata_new_from_file(src);
-		pixbuf = metadata->thumbnail;
-
-		if (pixbuf)
-			g_object_ref(pixbuf);
-		g_object_unref(metadata);
-	}
-
-	return pixbuf;
-}
-
 void
 rs_white_black_point(RS_BLOB *rs)
 {
@@ -1026,54 +961,49 @@
 		gboolean wb_ok = FALSE;
 		gboolean focallength_ok = FALSE;
 
-		RSMetadata *metadata = rs_metadata_new();
-
 		g_strstrip(filename);
-		RS_FILETYPE *filetype = rs_filetype_get(filename, TRUE);
 
-		if (filetype)
+		if (rs_filetype_can_load(filename))
 		{
+			RS_PHOTO *photo = NULL;
 			filetype_ok = TRUE;
-			if (filetype->load)
+			photo = rs_photo_load_from_file(filename, TRUE);
+			if (photo)
 			{
-				RS_PHOTO *photo = NULL;
-				photo = rs_photo_load_from_file(filename, TRUE);
-				if (photo)
-				{
-					load_ok = TRUE;
-					g_object_unref(photo);
-				}
+				load_ok = TRUE;
+				g_object_unref(photo);
 			}
 
-			pixbuf = rs_load_thumb(filetype, filename);
+			RSMetadata *metadata = rs_metadata_new_from_file(filename);
+
+			load_meta_ok = TRUE;
+
+			if (metadata->make != MAKE_UNKNOWN)
+				make_ok = TRUE;
+			if (metadata->make_ascii != NULL)
+				make_ascii_ok = TRUE;
+			if (metadata->model_ascii != NULL)
+				model_ascii_ok = TRUE;
+			if (metadata->aperture > 0.0)
+				aperture_ok = TRUE;
+			if (metadata->iso > 0)
+				iso_ok = TRUE;
+			if (metadata->shutterspeed > 1.0)
+				shutterspeed_ok = TRUE;
+			if (metadata->cam_mul[0] > 0.1 && metadata->cam_mul[0] != 1.0)
+				wb_ok = TRUE;
+			if (metadata->focallength > 0.0)
+				focallength_ok = TRUE;
+
+			/* FIXME: Port to RSFiletype */
+			pixbuf = rs_metadata_get_thumbnail(metadata);
 			if (pixbuf)
 			{
 				thumbnail_ok = TRUE;
 				g_object_unref(pixbuf);
 			}
+			g_object_unref(metadata);
 
-			if (filetype->load_meta)
-			{
-				load_meta_ok = TRUE;
-				filetype->load_meta(filename, metadata);
-				if (metadata->make != MAKE_UNKNOWN)
-					make_ok = TRUE;
-				if (metadata->make_ascii != NULL)
-					make_ascii_ok = TRUE;
-				if (metadata->model_ascii != NULL)
-					model_ascii_ok = TRUE;
-				if (metadata->aperture > 0.0)
-					aperture_ok = TRUE;
-				if (metadata->iso > 0)
-					iso_ok = TRUE;
-				if (metadata->shutterspeed > 1.0)
-					shutterspeed_ok = TRUE;
-				if (metadata->cam_mul[0] > 0.1 && metadata->cam_mul[0] != 1.0)
-					wb_ok = TRUE;
-				if (metadata->focallength > 0.0)
-					focallength_ok = TRUE;
-			}
-
 		}
 
 		basename = g_path_get_basename(filename);
@@ -1111,7 +1041,6 @@
 		g_free(basename);
 
 		g_free(filename);
-		g_object_unref(metadata);
 	}
 	printf("Passed: %d Failed: %d (%d%%)\n", good, bad, (good*100)/(good+bad));
 	g_io_channel_shutdown(io, TRUE, NULL);

Modified: trunk/src/rawstudio.h
===================================================================
--- trunk/src/rawstudio.h	2008-09-17 21:29:52 UTC (rev 2020)
+++ trunk/src/rawstudio.h	2008-09-22 05:58:06 UTC (rev 2021)
@@ -256,8 +256,6 @@
 	gint filetype;
 	const gchar *ext;
 	gchar *description;
-	RS_IMAGE16 *(*load)(const gchar *, gboolean);
-	void (*load_meta)(const gchar *, RSMetadata *);
 	gboolean (*save)(RS_PHOTO *photo, const gchar *filename, gint filetype, gint width, gint height, gboolean keep_aspect, gdouble scale, gint snapshot, RS_CMS *cms);
 	struct _rs_filetype *next;
 } RS_FILETYPE;
@@ -266,7 +264,6 @@
 extern GMutex *omp_lock;
 #endif /* __RS_USE_OMP */
 
-GdkPixbuf *rs_load_thumb(RS_FILETYPE *filetype, const gchar *src);
 void rs_local_cachedir(gboolean new_value);
 void rs_load_gdk(gboolean new_value);
 void rs_reset(RS_BLOB *rs);
@@ -283,7 +280,6 @@
 void rs_free(RS_BLOB *rs);
 void rs_set_photo(RS_BLOB *rs, RS_PHOTO *photo);
 void rs_set_snapshot(RS_BLOB *rs, gint snapshot);
-RS_FILETYPE *rs_filetype_get(const gchar *filename, gboolean load);
 gchar *rs_confdir_get();
 gchar *rs_dotdir_get(const gchar *filename);
 gchar *rs_thumb_get_name(const gchar *src);

Modified: trunk/src/rs-actions.c
===================================================================
--- trunk/src/rs-actions.c	2008-09-17 21:29:52 UTC (rev 2020)
+++ trunk/src/rs-actions.c	2008-09-22 05:58:06 UTC (rev 2021)
@@ -415,7 +415,6 @@
 		if(mask > 0)
 		{
 			RS_PHOTO *photo;
-			RS_FILETYPE *filetype;
 			gint cur;
 			GList *selected = NULL;
 			gint num_selected;
@@ -429,12 +428,9 @@
 				/* This is nothing but a hack around rs_cache_*() */
 				photo = rs_photo_new();
 				photo->filename = g_strdup(g_list_nth_data(selected, cur));
-				if ((filetype = rs_filetype_get(photo->filename, TRUE)))
-				{
-					new_mask = rs_cache_load(photo);
-					rs_settings_double_copy(rs->settings_buffer, photo->settings[rs->current_setting], mask);
-					rs_cache_save(photo, new_mask | mask);
-				}
+				new_mask = rs_cache_load(photo);
+				rs_settings_double_copy(rs->settings_buffer, photo->settings[rs->current_setting], mask);
+				rs_cache_save(photo, new_mask | mask);
 				g_object_unref(photo);
 			}
 			g_list_free(selected);

Modified: trunk/src/rs-batch.c
===================================================================
--- trunk/src/rs-batch.c	2008-09-17 21:29:52 UTC (rev 2020)
+++ trunk/src/rs-batch.c	2008-09-22 05:58:06 UTC (rev 2021)
@@ -204,8 +204,8 @@
 	gboolean ret = FALSE;
 	if (!rs_batch_exists_in_queue(queue, filename, setting_id))
 	{
+		RSMetadata *metadata;
 		gchar *filename_short, *setting_id_abc;
-		RS_FILETYPE *filetype;
 		GdkPixbuf *pixbuf = NULL, *missing_thumb, *pixbuf_temp;
 
 		filename_short = g_path_get_basename(filename);
@@ -225,59 +225,58 @@
 				return ret;
 		}
 
-		filetype = rs_filetype_get(filename, TRUE);
-		if (filetype)
-		{
-			missing_thumb = gtk_widget_render_icon(GTK_WIDGET(rawstudio_window),
-				GTK_STOCK_MISSING_IMAGE, GTK_ICON_SIZE_DIALOG, NULL);
+		missing_thumb = gtk_widget_render_icon(GTK_WIDGET(rawstudio_window),
+			GTK_STOCK_MISSING_IMAGE, GTK_ICON_SIZE_DIALOG, NULL);
 
-			pixbuf = rs_load_thumb(filetype, filename);
-			if (pixbuf)
-			{
-				gint w,h,temp,size = 48;
+		metadata = rs_metadata_new_from_file(filename);
+		pixbuf = rs_metadata_get_thumbnail(metadata);
+		g_object_unref(metadata);
 
-				w = gdk_pixbuf_get_width(pixbuf);
-				h = gdk_pixbuf_get_height(pixbuf);
+		if (pixbuf)
+		{
+			gint w,h,temp,size = 48;
 
-				if (w > h)
-				{
-					temp = 1000*h/w;
-					pixbuf_temp = gdk_pixbuf_scale_simple(pixbuf, size, size*temp/1000, GDK_INTERP_BILINEAR);
-					g_object_unref(pixbuf);
-					pixbuf = pixbuf_temp;
-				}
-				else
-				{
-					temp = 1000*w/h;
-					pixbuf_temp = gdk_pixbuf_scale_simple(pixbuf, size*temp/1000, size, GDK_INTERP_BILINEAR);
-					g_object_unref(pixbuf);
-					pixbuf = pixbuf_temp;
-				}
+			w = gdk_pixbuf_get_width(pixbuf);
+			h = gdk_pixbuf_get_height(pixbuf);
+
+			if (w > h)
+			{
+				temp = 1000*h/w;
+				pixbuf_temp = gdk_pixbuf_scale_simple(pixbuf, size, size*temp/1000, GDK_INTERP_BILINEAR);
+				g_object_unref(pixbuf);
+				pixbuf = pixbuf_temp;
 			}
 			else
 			{
-				pixbuf = missing_thumb;
-				g_object_ref (pixbuf);
+				temp = 1000*w/h;
+				pixbuf_temp = gdk_pixbuf_scale_simple(pixbuf, size*temp/1000, size, GDK_INTERP_BILINEAR);
+				g_object_unref(pixbuf);
+				pixbuf = pixbuf_temp;
 			}
-			g_object_unref(missing_thumb);
+		}
+		else
+		{
+			pixbuf = missing_thumb;
+			g_object_ref (pixbuf);
+		}
+		g_object_unref(missing_thumb);
 
-			if (!rs_batch_exists_in_queue(queue, filename, setting_id))
-			{
-				GtkTreeIter iter;
+		if (!rs_batch_exists_in_queue(queue, filename, setting_id))
+		{
+			GtkTreeIter iter;
 
-				gtk_list_store_append (GTK_LIST_STORE(queue->list), &iter);
-				gtk_list_store_set (GTK_LIST_STORE(queue->list), &iter,
-					RS_QUEUE_ELEMENT_FILENAME, filename,
-					RS_QUEUE_ELEMENT_FILENAME_SHORT, filename_short,
-					RS_QUEUE_ELEMENT_SETTING_ID, setting_id,
-					RS_QUEUE_ELEMENT_SETTING_ID_ABC, setting_id_abc,
-					RS_QUEUE_ELEMENT_THUMBNAIL, pixbuf,
-					-1);
-				ret = TRUE;
-			}
-			g_object_unref(pixbuf);
-			g_free(filename_short);
+			gtk_list_store_append (GTK_LIST_STORE(queue->list), &iter);
+			gtk_list_store_set (GTK_LIST_STORE(queue->list), &iter,
+				RS_QUEUE_ELEMENT_FILENAME, filename,
+				RS_QUEUE_ELEMENT_FILENAME_SHORT, filename_short,
+				RS_QUEUE_ELEMENT_SETTING_ID, setting_id,
+				RS_QUEUE_ELEMENT_SETTING_ID_ABC, setting_id_abc,
+				RS_QUEUE_ELEMENT_THUMBNAIL, pixbuf,
+				-1);
+			ret = TRUE;
 		}
+		g_object_unref(pixbuf);
+		g_free(filename_short);
 	}
 
 	batch_queue_save(queue);
@@ -484,70 +483,67 @@
 			RS_QUEUE_ELEMENT_FILENAME, &filename_in,
 			RS_QUEUE_ELEMENT_SETTING_ID, &setting_id,
 			-1);
-		if (rs_filetype_get(filename_in, TRUE))
+		basename = g_path_get_basename(filename_in);
+		g_string_printf(status, _("Loading %s ..."), basename);
+		gtk_label_set_text(GTK_LABEL(label), status->str);
+		while (gtk_events_pending()) gtk_main_iteration();
+		g_free(basename);
+
+		photo = rs_photo_load_from_file(filename_in, FALSE);
+		rs_image16_demosaic(photo->input, RS_DEMOSAIC_PPG);
+		if (photo)
 		{
-			basename = g_path_get_basename(filename_in);
-			g_string_printf(status, _("Loading %s ..."), basename);
-			gtk_label_set_text(GTK_LABEL(label), status->str);
-			while (gtk_events_pending()) gtk_main_iteration();
-			g_free(basename);
+			rs_metadata_load_from_file(photo->metadata, filename_in);
+			filename = g_string_new(queue->directory);
+			g_string_append(filename, G_DIR_SEPARATOR_S);
+			g_string_append(filename, queue->filename);
+			g_string_append(filename, ".");
 
-			photo = rs_photo_load_from_file(filename_in, FALSE);
-			rs_image16_demosaic(photo->input, RS_DEMOSAIC_PPG);
-			if (photo)
+			switch (queue->filetype)
 			{
-				rs_metadata_load_from_file(photo->metadata, filename_in);
-				filename = g_string_new(queue->directory);
-				g_string_append(filename, G_DIR_SEPARATOR_S);
-				g_string_append(filename, queue->filename);
-				g_string_append(filename, ".");
+				case FILETYPE_JPEG:
+					g_string_append(filename, "jpg");
+					break;
+				case FILETYPE_PNG:
+					g_string_append(filename, "png");
+					break;
+				case FILETYPE_TIFF8:
+					g_string_append(filename, "tif");
+					break;
+				case FILETYPE_TIFF16:
+					g_string_append(filename, "tif");
+					break;
+			}
 
-				switch (queue->filetype)
-				{
-					case FILETYPE_JPEG:
-						g_string_append(filename, "jpg");
-						break;
-					case FILETYPE_PNG:
-						g_string_append(filename, "png");
-						break;
-					case FILETYPE_TIFF8:
-						g_string_append(filename, "tif");
-						break;
-					case FILETYPE_TIFF16:
-						g_string_append(filename, "tif");
-						break;
-				}
+			rs_cache_load(photo);
 
-				rs_cache_load(photo);
+			parsed_filename = filename_parse(filename->str, filename_in, setting_id);
 
-				parsed_filename = filename_parse(filename->str, filename_in, setting_id);
+			image = rs_image16_transform(photo->input, NULL,
+				NULL, NULL, photo->crop, 200, 200, TRUE, -1.0,
+				photo->angle, photo->orientation, NULL);
+			if (pixbuf) g_object_unref(pixbuf);
+			pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, image->w, image->h);
 
-				image = rs_image16_transform(photo->input, NULL,
-					NULL, NULL, photo->crop, 200, 200, TRUE, -1.0,
-					photo->angle, photo->orientation, NULL);
-				if (pixbuf) g_object_unref(pixbuf);
-				pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, image->w, image->h);
+			/* Render preview image */
+			rs_color_transform_set_from_settings(rct, photo->settings[setting_id], MASK_ALL);
+			rs_color_transform_transform(rct, image->w, image->h, image->pixels,
+				image->rowstride, gdk_pixbuf_get_pixels(pixbuf),
+				gdk_pixbuf_get_rowstride(pixbuf));
+			gtk_image_set_from_pixbuf((GtkImage *) preview, pixbuf);
+			rs_image16_free(image);
 
-				/* Render preview image */
-				rs_color_transform_set_from_settings(rct, photo->settings[setting_id], MASK_ALL);
-				rs_color_transform_transform(rct, image->w, image->h, image->pixels,
-					image->rowstride, gdk_pixbuf_get_pixels(pixbuf),
-					gdk_pixbuf_get_rowstride(pixbuf));
-				gtk_image_set_from_pixbuf((GtkImage *) preview, pixbuf);
-				rs_image16_free(image);
+			basename = g_path_get_basename(parsed_filename);
+			g_string_printf(status, _("Saving %s ..."), basename);
+			gtk_label_set_text(GTK_LABEL(label), status->str);
+			while (gtk_events_pending()) gtk_main_iteration();
+			g_free(basename);
 
-				basename = g_path_get_basename(parsed_filename);
-				g_string_printf(status, _("Saving %s ..."), basename);
-				gtk_label_set_text(GTK_LABEL(label), status->str);
-				while (gtk_events_pending()) gtk_main_iteration();
-				g_free(basename);
-
-				rs_photo_save(photo, parsed_filename, queue->filetype,
-					width, height, TRUE, scale, setting_id, queue->cms);
-				g_free(parsed_filename);
-				g_string_free(filename, TRUE);
-				g_object_unref(photo);
-			}
+			rs_photo_save(photo, parsed_filename, queue->filetype,
+				width, height, TRUE, scale, setting_id, queue->cms);
+			g_free(parsed_filename);
+			g_string_free(filename, TRUE);
+			g_object_unref(photo);
 			photo = NULL;
 		}
 		gtk_list_store_remove(GTK_LIST_STORE(queue->list), &iter);

Added: trunk/src/rs-filetypes.c
===================================================================
--- trunk/src/rs-filetypes.c	                        (rev 0)
+++ trunk/src/rs-filetypes.c	2008-09-22 05:58:06 UTC (rev 2021)
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2006-2008 Anders Brander <anders at brander.dk> and 
+ * Anders Kvist <akv at lnxbx.dk>
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include "rs-filetypes.h"
+
+static gint tree_sort(gconstpointer a, gconstpointer b);
+static gint tree_search_func(gconstpointer a, gconstpointer b);
+static gpointer filetype_search(GTree *tree, const gchar *filename, gint *priority);
+static void filetype_add_to_tree(GTree *tree, const gchar *extension, const gchar *description, const gpointer func, const gint priority);
+
+static gboolean rs_filetype_is_initialized = FALSE;
+static GStaticMutex lock = G_STATIC_MUTEX_INIT;
+static GTree *loaders = NULL;
+static GTree *meta_loaders = NULL;
+
+typedef struct {
+	gchar *extension;
+	gchar *description;
+	gint priority;
+} RSFiletype;
+
+struct search_needle {
+	gchar *extension;
+	gint *priority;
+};
+
+static gint
+tree_sort(gconstpointer a, gconstpointer b)
+{
+	gint extension;
+	RSFiletype *type_a = (RSFiletype *) a;
+	RSFiletype *type_b = (RSFiletype *) b;
+
+	extension = g_utf8_collate(type_a->extension, type_b->extension);
+	if (extension == 0)
+		return type_b->priority - type_a->priority;
+	else
+		return extension;
+}
+
+static gint
+tree_search_func(gconstpointer a, gconstpointer b)
+{
+	gint extension;
+	RSFiletype *type_a = (RSFiletype *) a;
+	struct search_needle *needle = (struct search_needle *) b;
+	extension = g_utf8_collate(needle->extension, type_a->extension);
+
+	if (extension == 0)
+	{
+		if (type_a->priority > *(needle->priority))
+		{
+			*(needle->priority) = type_a->priority;
+			return 0;
+		}
+		else
+			return -1;
+	}
+
+	return extension;
+}
+
+static gpointer
+filetype_search(GTree *tree, const gchar *filename, gint *priority)
+{
+	gpointer func = NULL;
+	const gchar *extension;
+
+	extension = g_strrstr(filename, ".");
+
+	if (extension)
+	{
+		struct search_needle needle;
+
+		needle.extension = g_utf8_strdown(extension, -1);
+		needle.priority = priority;
+		g_static_mutex_lock(&lock);
+		func = g_tree_search(tree, tree_search_func, &needle);
+		g_static_mutex_unlock(&lock);
+
+		g_free(needle.extension);
+	}
+
+	return func;
+}
+
+static void
+filetype_add_to_tree(GTree *tree, const gchar *extension, const gchar *description, const gpointer func, const gint priority)
+{
+	RSFiletype *filetype = g_new(RSFiletype, 1);
+
+	g_assert(rs_filetype_is_initialized);
+	g_assert(tree != NULL);
+	g_assert(extension != NULL);
+	g_assert(extension[0] == '.');
+	g_assert(description != NULL);
+	g_assert(func != NULL);
+	g_assert(priority > 0);
+
+	filetype->extension = g_strdup(extension);
+	filetype->description = g_strdup(description);
+	filetype->priority = priority;
+
+	g_static_mutex_lock(&lock);
+	g_tree_insert(tree, filetype, func);
+	g_static_mutex_unlock(&lock);
+}
+
+/**
+ * Initialize the RSFiletype subsystem, this MUST be called before any other
+ * rs_filetype_*-functions
+ */
+void
+rs_filetype_init()
+{
+	g_static_mutex_lock(&lock);
+	if (rs_filetype_is_initialized)
+		return;
+	rs_filetype_is_initialized = TRUE;
+	loaders = g_tree_new(tree_sort);
+	meta_loaders = g_tree_new(tree_sort);
+	g_static_mutex_unlock(&lock);
+}
+
+/**
+ * Register a new image loader
+ * @param extension The filename extension including the dot, ie: ".cr2"
+ * @param description A human readable description of the file-format/loader
+ * @param loader The loader function
+ * @param priority A loader priority, lowest is served first.
+ */
+void
+rs_filetype_register_loader(const gchar *extension, const gchar *description, const RSFileLoaderFunc loader, const gint priority)
+{
+	filetype_add_to_tree(loaders, extension, description, loader, priority);
+}
+
+/**
+ * Register a new metadata loader
+ * @param extension The filename extension including the dot, ie: ".cr2"
+ * @param description A human readable description of the file-format/loader
+ * @param meta_loader The loader function
+ * @param priority A loader priority, lowest is served first.
+ */
+void
+rs_filetype_register_meta_loader(const gchar *extension, const gchar *description, const RSFileMetaLoaderFunc meta_loader, const gint priority)
+{
+	filetype_add_to_tree(meta_loaders, extension, description, meta_loader, priority);
+}
+
+/**
+ * Check if we support loading a given extension
+ * @param filename A filename or extension to look-up
+ */
+gboolean
+rs_filetype_can_load(const gchar *filename)
+{
+	gboolean can_load = FALSE;
+	gint priority = 0;
+	
+	g_assert(rs_filetype_is_initialized);
+	g_assert(filename != NULL);
+
+	if (filetype_search(loaders, filename, &priority))
+		can_load = TRUE;
+
+	return can_load;
+}
+
+/**
+ * Load an image according to registered loaders
+ * @param filename The file to load
+ * @param half_size Set to TRUE to avoid preparing image for debayer
+ * @return A new RS_IMAGE16 or NULL if the loading failed
+ */
+RS_IMAGE16 *
+rs_filetype_load(const gchar *filename, const gboolean half_size)
+{
+	RS_IMAGE16 *image = NULL;
+	gint priority = 0;
+	RSFileLoaderFunc loader;
+
+	g_assert(rs_filetype_is_initialized);
+	g_assert(filename != NULL);
+
+	while((loader = filetype_search(loaders, filename, &priority)) && !image)
+		image = loader(filename, half_size);
+
+	return image;
+}
+
+/**
+ * Load metadata from a specified file
+ * @param filename The file to load metadata from
+ * @param meta A RSMetadata structure to load everything into
+ */
+void
+rs_filetype_meta_load(const gchar *filename, RSMetadata *meta)
+{
+	gint priority = 0;
+	RSFileMetaLoaderFunc loader;
+
+	g_assert(rs_filetype_is_initialized);
+	g_assert(filename != NULL);
+	g_assert(RS_IS_METADATA(meta));
+
+	while((loader = filetype_search(meta_loaders, filename, &priority)))
+	{
+		loader(filename, meta);
+	}
+}

Added: trunk/src/rs-filetypes.h
===================================================================
--- trunk/src/rs-filetypes.h	                        (rev 0)
+++ trunk/src/rs-filetypes.h	2008-09-22 05:58:06 UTC (rev 2021)
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2006-2008 Anders Brander <anders at brander.dk> and 
+ * Anders Kvist <akv at lnxbx.dk>
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+#ifndef RS_FILETYPES_H
+#define RS_FILETYPES_H
+
+#include "rs-metadata.h"
+#include "rs-image.h"
+
+typedef RS_IMAGE16 *(*RSFileLoaderFunc)(const gchar *filename, const gboolean half_size);
+typedef void (*RSFileMetaLoaderFunc)(const gchar *filename, RSMetadata *meta);
+typedef gboolean (*RSFileSaverFunc)(RS_PHOTO *photo, const gchar *filename, const gint width, const gint height, const gboolean keep_aspect, const gdouble scale, const gint snapshot, const RS_CMS *cms);
+
+/**
+ * Initialize the RSFiletype subsystem, this MUST be called before any other
+ * rs_filetype_*-functions
+ */
+extern void rs_filetype_init();
+
+/**
+ * Register a new image loader
+ * @param extension The filename extension including the dot, ie: ".cr2"
+ * @param description A human readable description of the file-format/loader
+ * @param loader The loader function
+ * @param priority A loader priority, lowest is served first.
+ */
+extern void rs_filetype_register_loader(const gchar *extension, const gchar *description, const RSFileLoaderFunc loader, const gint priority);
+
+/**
+ * Register a new metadata loader
+ * @param extension The filename extension including the dot, ie: ".cr2"
+ * @param description A human readable description of the file-format/loader
+ * @param meta_loader The loader function
+ * @param priority A loader priority, lowest is served first.
+ */
+extern void rs_filetype_register_meta_loader(const gchar *extension, const gchar *description, const RSFileMetaLoaderFunc meta_loader, const gint priority);
+
+/**
+ * Check if we support loading a given extension
+ * @param filename A filename or extension to look-up
+ */
+extern gboolean rs_filetype_can_load(const gchar *filename);
+
+/**
+ * Load an image according to registered loaders
+ * @param filename The file to load
+ * @param half_size Set to TRUE to avoid preparing image for debayer
+ * @return A new RS_IMAGE16 or NULL if the loading failed
+ */
+extern RS_IMAGE16 *rs_filetype_load(const gchar *filename, const gboolean half_size);
+
+/**
+ * Load metadata from a specified file
+ * @param filename The file to load metadata from
+ * @param meta A RSMetadata structure to load everything into
+ */
+extern void rs_filetype_meta_load(const gchar *filename, RSMetadata *meta);
+
+#endif /* RS_FILETYPES_H */

Modified: trunk/src/rs-metadata.c
===================================================================
--- trunk/src/rs-metadata.c	2008-09-17 21:29:52 UTC (rev 2020)
+++ trunk/src/rs-metadata.c	2008-09-22 05:58:06 UTC (rev 2021)
@@ -22,6 +22,7 @@
 #include "rs-metadata.h"
 #include "rawstudio.h"
 #include "rs-math.h"
+#include "rs-filetypes.h"
 
 G_DEFINE_TYPE (RSMetadata, rs_metadata, G_TYPE_OBJECT)
 
@@ -118,19 +119,14 @@
 rs_metadata_load_from_file(RSMetadata *metadata, const gchar *filename)
 {
 	gboolean ret = FALSE;
-	RS_FILETYPE *filetype;
 
 	g_assert(filename != NULL);
 	g_assert(RS_IS_METADATA(metadata));
 
-	filetype = rs_filetype_get(filename, TRUE);
+	/* FIXME: Fix the damned return value from meta-loaders! */
+	ret = TRUE;
+	rs_filetype_meta_load(filename, metadata);
 
-	if (filetype && filetype->load_meta)
-	{
-		filetype->load_meta(filename, metadata);
-		ret = TRUE;
-	}
-
 	return ret;
 }
 

Modified: trunk/src/rs-photo.c
===================================================================
--- trunk/src/rs-photo.c	2008-09-17 21:29:52 UTC (rev 2020)
+++ trunk/src/rs-photo.c	2008-09-22 05:58:06 UTC (rev 2021)
@@ -24,6 +24,7 @@
 #include "rs-curve.h"
 #include "rs-preload.h"
 #include "rs-metadata.h"
+#include "rs-filetypes.h"
 
 static void rs_photo_class_init (RS_PHOTOClass *klass);
 
@@ -561,7 +562,6 @@
 rs_photo_load_from_file(const gchar *filename, gboolean half_size)
 {
 	RS_PHOTO *photo = NULL;
-	RS_FILETYPE *filetype;
 	RS_IMAGE16 *image;
 	guint mask;
 	gint i;
@@ -571,55 +571,49 @@
 	if (photo)
 		return photo;
 
-	filetype = rs_filetype_get(filename, TRUE);
-
-	if (filetype && filetype->load)
+	image = rs_filetype_load(filename, half_size);
+	if (image)
 	{
-		image = filetype->load(filename, half_size);
+		photo = rs_photo_new();
 
-		if (image)
-		{
-			photo = rs_photo_new();
+		/* Set filename */
+		photo->filename = g_strdup(filename);
 
-			/* Set filename */
-			photo->filename = g_strdup(filename);
+		/* Set input image */
+		photo->input = image;
 
-			/* Set input image */
-			photo->input = image;
-
-			/* Load metadata */
-			if (rs_metadata_load_from_file(photo->metadata, filename))
+		/* Load metadata */
+		if (rs_metadata_load_from_file(photo->metadata, filename))
+		{
+			/* Rotate photo inplace */
+			switch (photo->metadata->orientation)
 			{
-				/* Rotate photo inplace */
-				switch (photo->metadata->orientation)
-				{
-					case 90: ORIENTATION_90(photo->orientation);
-						break;
-					case 180: ORIENTATION_180(photo->orientation);
-						break;
-					case 270: ORIENTATION_270(photo->orientation);
-						break;
-				}
+				case 90: ORIENTATION_90(photo->orientation);
+					break;
+				case 180: ORIENTATION_180(photo->orientation);
+					break;
+				case 270: ORIENTATION_270(photo->orientation);
+					break;
 			}
+		}
 
-			/* Load cache */
-			mask = rs_cache_load(photo);
-			/* If we have no cache, try to set some sensible defaults */
-			for (i=0;i<3;i++)
-			{
-				/* White balance */
-				if (!(mask & MASK_WB))
-					if (!rs_photo_set_wb_from_camera(photo, i))
-						rs_photo_set_wb_auto(photo, i);
+		/* Load cache */
+		mask = rs_cache_load(photo);
+		/* If we have no cache, try to set some sensible defaults */
+		for (i=0;i<3;i++)
+		{
+			/* White balance */
+			if (!(mask & MASK_WB))
+				if (!rs_photo_set_wb_from_camera(photo, i))
+					rs_photo_set_wb_auto(photo, i);
 
-				/* Contrast */
-				if (!(mask & MASK_CONTRAST) && (photo->metadata->contrast != -1.0))
-					rs_photo_set_contrast(photo, i, photo->metadata->contrast);
+			/* Contrast */
+			if (!(mask & MASK_CONTRAST) && (photo->metadata->contrast != -1.0))
+				rs_photo_set_contrast(photo, i, photo->metadata->contrast);
 
-				/* Saturation */
-				if (!(mask & MASK_SATURATION) && (photo->metadata->saturation != -1.0))
-					rs_photo_set_saturation(photo, i, photo->metadata->saturation);
-			}
+			/* Saturation */
+			if (!(mask & MASK_SATURATION) && (photo->metadata->saturation != -1.0))
+				rs_photo_set_saturation(photo, i, photo->metadata->saturation);
 		}
 	}
 

Modified: trunk/src/rs-store.c
===================================================================
--- trunk/src/rs-store.c	2008-09-17 21:29:52 UTC (rev 2020)
+++ trunk/src/rs-store.c	2008-09-22 05:58:06 UTC (rev 2021)
@@ -35,6 +35,7 @@
 #include "rs-preload.h"
 #include "rs-photo.h"
 #include "rs-metadata.h"
+#include "rs-filetypes.h"
 
 /* How many different icon views do we have (tabs) */
 #define NUM_VIEWS 6
@@ -979,7 +980,6 @@
 find_loadable(const gchar *path, gboolean load_8bit, gboolean load_recursive)
 {
 	gchar *name;
-	RS_FILETYPE *filetype;
 	GString *fullname;
 	GList *loadable = NULL;
 	GDir *dir = g_dir_open(path, 0, NULL);
@@ -992,14 +992,11 @@
 		fullname = g_string_new(path);
 		fullname = g_string_append(fullname, G_DIR_SEPARATOR_S);
 		fullname = g_string_append(fullname, name);
-		filetype = rs_filetype_get(name, TRUE);
-		if (filetype)
-		{
-			if (filetype->load && ((filetype->filetype==FILETYPE_RAW)||load_8bit))
-			{
-				loadable = g_list_append(loadable, fullname->str);
-			}
-		}
+
+		/* FIXME: deal with 8-bit-switch! */
+		if (rs_filetype_can_load(name))
+			loadable = g_list_append(loadable, fullname->str);
+
 		if (load_recursive)
 		{
 			if (g_file_test(fullname->str, G_FILE_TEST_IS_DIR))
@@ -1032,7 +1029,6 @@
 load_loadable(RSStore *store, GList *loadable, RS_PROGRESS *rsp)
 {
 	gchar *name;
-	RS_FILETYPE *filetype;
 	GdkPixbuf *pixbuf;
 	GdkPixbuf *pixbuf_clean;
 	GdkPixbuf *missing_thumb;
@@ -1053,54 +1049,50 @@
 		fullname = g_list_nth_data(loadable, n);
 		name = g_path_get_basename(fullname);
 
-		filetype = rs_filetype_get(name, TRUE);
-		if (filetype)
+		if (rs_filetype_can_load(name))
 		{
-			if (filetype->load)
-			{
-				RSMetadata *metadata = rs_metadata_new_from_file(fullname);
+			RSMetadata *metadata = rs_metadata_new_from_file(fullname);
 
-				pixbuf = rs_metadata_get_thumbnail(metadata);
+			pixbuf = rs_metadata_get_thumbnail(metadata);
 
-				if (pixbuf==NULL)
-				{
-					pixbuf = gdk_pixbuf_copy(missing_thumb);
-					g_object_ref (pixbuf);
-				}
+			if (pixbuf==NULL)
+			{
+				pixbuf = gdk_pixbuf_copy(missing_thumb);
+				g_object_ref (pixbuf);
+			}
 
-				/* Save a clean copy of the thumbnail for later use */
-				pixbuf_clean = gdk_pixbuf_copy(pixbuf);
+			/* Save a clean copy of the thumbnail for later use */
+			pixbuf_clean = gdk_pixbuf_copy(pixbuf);
 
-				/* Sane defaults */
-				priority = PRIO_U;
-				exported = FALSE;
+			/* Sane defaults */
+			priority = PRIO_U;
+			exported = FALSE;
 
-				/* Load flags from XML cache */
-				rs_cache_load_quick(fullname, &priority, &exported);
+			/* Load flags from XML cache */
+			rs_cache_load_quick(fullname, &priority, &exported);
 
-				/* Update thumbnail */
-				thumbnail_update(pixbuf, pixbuf_clean, priority, exported);
+			/* Update thumbnail */
+			thumbnail_update(pixbuf, pixbuf_clean, priority, exported);
 
-				/* Add thumbnail to store */
-				gtk_list_store_prepend (store->store, &iter);
-				gtk_list_store_set (store->store, &iter,
-					PIXBUF_COLUMN, pixbuf,
-					PIXBUF_CLEAN_COLUMN, pixbuf_clean,
-					TEXT_COLUMN, name,
-					FULLNAME_COLUMN, fullname,
-					PRIORITY_COLUMN, priority,
-					EXPORTED_COLUMN, exported,
-					METADATA_COLUMN, metadata,
-					-1);
+			/* Add thumbnail to store */
+			gtk_list_store_prepend (store->store, &iter);
+			gtk_list_store_set (store->store, &iter,
+				PIXBUF_COLUMN, pixbuf,
+				PIXBUF_CLEAN_COLUMN, pixbuf_clean,
+				TEXT_COLUMN, name,
+				FULLNAME_COLUMN, fullname,
+				PRIORITY_COLUMN, priority,
+				EXPORTED_COLUMN, exported,
+				METADATA_COLUMN, metadata,
+				-1);
 
-				/* We can safely unref by now, store holds a reference */
-				g_object_unref (metadata);
-				g_object_unref (pixbuf);
-				g_object_unref (pixbuf_clean);
+			/* We can safely unref by now, store holds a reference */
+			g_object_unref (metadata);
+			g_object_unref (pixbuf);
+			g_object_unref (pixbuf_clean);
 
-				/* Move our progress bar */
-				gui_progress_advance_one(rsp);
-			}
+			/* Move our progress bar */
+			gui_progress_advance_one(rsp);
 		}
 		g_free(name);
 	}
@@ -2168,7 +2160,6 @@
 void
 rs_store_auto_group(RSStore *store)
 {
-	RS_FILETYPE *filetype = NULL;
 	gchar *filename = NULL;
 	gint timestamp = 0, timestamp_old = 0;
 	gint exposure;
@@ -2182,31 +2173,24 @@
 	do
 	{
 		store_get_fullname(GTK_LIST_STORE(store->store), &iter, &filename);
-		filetype = rs_filetype_get(filename, TRUE);
-		if (filetype)
-		{
-			if(filetype->load_meta)
-			{
-				meta = rs_metadata_new();
-				filetype->load_meta(filename, meta);
-				
-				if (!meta->timestamp)
-					return;
-				
-				timestamp = meta->timestamp;
-				exposure = (1/meta->shutterspeed);
+		meta = rs_metadata_new_from_file(filename);
 
-				if (timestamp > timestamp_old + 1)
-				{
-					if (g_list_length(filenames) > 1)
-						store_group_photos_by_filenames(store->store, filenames);
-					g_list_free(filenames);
-					filenames = NULL;
-				}
-				timestamp_old = timestamp + exposure;
-				g_free(meta);
-			}
+		if (!meta->timestamp)
+			return;
+
+		timestamp = meta->timestamp;
+		exposure = (1/meta->shutterspeed);
+
+		if (timestamp > timestamp_old + 1)
+		{
+			if (g_list_length(filenames) > 1)
+				store_group_photos_by_filenames(store->store, filenames);
+			g_list_free(filenames);
+			filenames = NULL;
 		}
+		timestamp_old = timestamp + exposure;
+		g_free(meta);
+
 		filenames = g_list_append(filenames, filename);
 	} while (gtk_tree_model_iter_next(GTK_TREE_MODEL(store->store), &iter));
 




More information about the Rawstudio-commit mailing list