123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356 |
- /*
- Raw photo loader plugin for The GIMP
- by Dave Coffin at cybercom dot net, user dcoffin
- http://www.cybercom.net/~dcoffin/
- $Revision: 1.32 $
- $Date: 2008/09/16 05:41:39 $
- This code is licensed under the same terms as The GIMP.
- To simplify maintenance, it calls my command-line "dcraw"
- program to do the actual decoding.
- To install locally:
- gimptool --install rawphoto.c
- To install globally:
- gimptool --install-admin rawphoto.c
- To build without installing:
- gcc -o rawphoto rawphoto.c `gtk-config --cflags --libs` -lgimp -lgimpui
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <gtk/gtk.h>
- #include <libgimp/gimp.h>
- #include <libgimp/gimpui.h>
- #if GIMP_CHECK_VERSION(1,3,2)
- #define GimpRunModeType GimpRunMode
- #endif
- #if GIMP_CHECK_VERSION(1,3,17)
- #define RAWPHOTO_CONST const
- #else
- #define RAWPHOTO_CONST
- #endif
- #include <locale.h>
- #include <libintl.h>
- #define _(String) gettext(String)
- #define PLUG_IN_VERSION "1.1.20 - 16 September 2008"
- static void query(void);
- static void run(RAWPHOTO_CONST gchar *name,
- gint nparams,
- RAWPHOTO_CONST GimpParam *param,
- gint *nreturn_vals,
- GimpParam **return_vals);
- static gint load_dialog (gchar *name);
- static gint32 load_image (gchar *filename);
- GimpPlugInInfo PLUG_IN_INFO =
- {
- NULL, /* init_procedure */
- NULL, /* quit_procedure */
- query, /* query_procedure */
- run, /* run_procedure */
- };
- static struct {
- gboolean check_val[6];
- gfloat spin_val[2];
- } cfg = {
- { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE },
- { 1, 0 }
- };
- MAIN ()
- static void query (void)
- {
- static GimpParamDef load_args[] =
- {
- { GIMP_PDB_INT32, "run_mode", "Interactive, non-interactive" },
- { GIMP_PDB_STRING, "filename", "The name of the file to load" },
- { GIMP_PDB_STRING, "raw_filename", "The name of the file to load" },
- };
- static GimpParamDef load_return_vals[] =
- {
- { GIMP_PDB_IMAGE, "image", "Output image" },
- };
- static gint num_load_args =
- sizeof load_args / sizeof load_args[0];
- static gint num_load_return_vals =
- sizeof load_return_vals / sizeof load_return_vals[0];
- gimp_install_procedure ("file_rawphoto_load",
- "Loads raw digital camera files",
- "This plug-in loads raw digital camera files.",
- "Dave Coffin at cybercom dot net, user dcoffin",
- "Copyright 2003-2008 by Dave Coffin",
- PLUG_IN_VERSION,
- "<Load>/rawphoto",
- NULL,
- GIMP_PLUGIN,
- num_load_args,
- num_load_return_vals,
- load_args,
- load_return_vals);
- gimp_register_load_handler ("file_rawphoto_load",
- "3fr,arw,bay,bmq,cine,cr2,crw,cs1,dc2,dcr,dng,erf,fff,hdr,ia,jpg,k25,kc2,kdc,mdc,mef,mos,mrw,nef,nrw,orf,pef,pxn,qtk,raf,raw,rdc,rw2,sr2,srf,sti,tif,x3f", "");
- }
- static void run (RAWPHOTO_CONST gchar *name,
- gint nparams,
- RAWPHOTO_CONST GimpParam *param,
- gint *nreturn_vals,
- GimpParam **return_vals)
- {
- static GimpParam values[2];
- GimpRunModeType run_mode;
- GimpPDBStatusType status;
- gint32 image_id = -1;
- gchar *command, *fname;
- int stat;
- *nreturn_vals = 1;
- *return_vals = values;
- status = GIMP_PDB_CALLING_ERROR;
- if (strcmp (name, "file_rawphoto_load")) goto done;
- status = GIMP_PDB_EXECUTION_ERROR;
- fname = param[1].data.d_string;
- command = g_malloc (strlen(fname)+20);
- if (!command) goto done;
- /*
- Is the file really a raw photo? If not, try loading it
- as a regular JPEG or TIFF.
- */
- sprintf (command, "dcraw -i '%s'\n",fname);
- fputs (command, stderr);
- stat = system (command);
- g_free (command);
- if (stat) {
- if (stat > 0x200)
- g_message (_("The \"rawphoto\" plugin won't work because "
- "there is no \"dcraw\" executable in your path."));
- if (!strcasecmp (fname + strlen(fname) - 4, ".jpg"))
- *return_vals = gimp_run_procedure2
- ("file_jpeg_load", nreturn_vals, nparams, param);
- else
- *return_vals = gimp_run_procedure2
- ("file_tiff_load", nreturn_vals, nparams, param);
- return;
- }
- gimp_get_data ("plug_in_rawphoto", &cfg);
- status = GIMP_PDB_CANCEL;
- run_mode = param[0].data.d_int32;
- if (run_mode == GIMP_RUN_INTERACTIVE)
- if (!load_dialog (param[1].data.d_string)) goto done;
- status = GIMP_PDB_EXECUTION_ERROR;
- image_id = load_image (param[1].data.d_string);
- if (image_id == -1) goto done;
- *nreturn_vals = 2;
- values[1].type = GIMP_PDB_IMAGE;
- values[1].data.d_image = image_id;
- status = GIMP_PDB_SUCCESS;
- gimp_set_data ("plug_in_rawphoto", &cfg, sizeof cfg);
- done:
- values[0].type = GIMP_PDB_STATUS;
- values[0].data.d_status = status;
- }
- static gint32 load_image (gchar *filename)
- {
- int tile_height, depth, width, height, row, nrows;
- FILE *pfp;
- gint32 image, layer;
- GimpDrawable *drawable;
- GimpPixelRgn pixel_region;
- guchar *pixel;
- char *command, nl;
- setlocale (LC_NUMERIC, "C");
- command = g_malloc (strlen(filename)+100);
- if (!command) return -1;
- sprintf (command,
- "dcraw -c%s%s%s%s%s%s -b %0.2f -H %d '%s'\n",
- cfg.check_val[0] ? " -q 0":"",
- cfg.check_val[1] ? " -h":"",
- cfg.check_val[2] ? " -f":"",
- cfg.check_val[3] ? " -d":"",
- cfg.check_val[4] ? " -a":"",
- cfg.check_val[5] ? " -w":"",
- cfg.spin_val[0], (int) cfg.spin_val[1],
- filename );
- fputs (command, stderr);
- pfp = popen (command, "r");
- g_free (command);
- if (!pfp) {
- perror ("dcraw");
- return -1;
- }
- if (fscanf (pfp, "P%d %d %d 255%c", &depth, &width, &height, &nl) != 4
- || (depth-5)/2 ) {
- pclose (pfp);
- g_message ("Not a raw digital camera image.\n");
- return -1;
- }
- depth = depth*2 - 9;
- image = gimp_image_new (width, height, depth == 3 ? GIMP_RGB : GIMP_GRAY);
- if (image == -1) {
- pclose (pfp);
- g_message ("Can't allocate new image.\n");
- return -1;
- }
- gimp_image_set_filename (image, filename);
- /* Create the "background" layer to hold the image... */
- layer = gimp_layer_new (image, "Background", width, height,
- depth == 3 ? GIMP_RGB_IMAGE : GIMP_GRAY_IMAGE,
- 100, GIMP_NORMAL_MODE);
- gimp_image_add_layer (image, layer, 0);
- /* Get the drawable and set the pixel region for our load... */
- drawable = gimp_drawable_get (layer);
- gimp_pixel_rgn_init (&pixel_region, drawable, 0, 0, drawable->width,
- drawable->height, TRUE, FALSE);
- /* Temporary buffers... */
- tile_height = gimp_tile_height();
- pixel = g_new (guchar, tile_height * width * depth);
- /* Load the image... */
- for (row = 0; row < height; row += tile_height) {
- nrows = height - row;
- if (nrows > tile_height)
- nrows = tile_height;
- fread (pixel, width * depth, nrows, pfp);
- gimp_pixel_rgn_set_rect (&pixel_region, pixel, 0, row, width, nrows);
- }
- pclose (pfp);
- g_free (pixel);
- gimp_drawable_flush (drawable);
- gimp_drawable_detach (drawable);
- return image;
- }
- #if !GIMP_CHECK_VERSION(1,3,23)
- /* this is set to true after OK click in any dialog */
- gboolean result = FALSE;
- static void callback_ok (GtkWidget * widget, gpointer data)
- {
- result = TRUE;
- gtk_widget_destroy (GTK_WIDGET (data));
- }
- #endif
- #define NCHECK (sizeof cfg.check_val / sizeof (gboolean))
- gint load_dialog (gchar * name)
- {
- GtkWidget *dialog;
- GtkWidget *table;
- GtkObject *adj;
- GtkWidget *widget;
- int i;
- static const char *label[9] =
- { "Quick interpolation", "Half-size interpolation",
- "Four color interpolation", "Grayscale document",
- "Automatic white balance", "Camera white balance",
- "Brightness", "Highlight mode" };
- gimp_ui_init ("rawphoto", TRUE);
- dialog = gimp_dialog_new (_("Raw Photo Loader " PLUG_IN_VERSION), "rawphoto",
- #if !GIMP_CHECK_VERSION(1,3,23)
- gimp_standard_help_func, "rawphoto",
- GTK_WIN_POS_MOUSE,
- FALSE, TRUE, FALSE,
- _("OK"), callback_ok, NULL, NULL, NULL, TRUE,
- FALSE, _("Cancel"), gtk_widget_destroy, NULL,
- 1, NULL, FALSE, TRUE, NULL);
- gtk_signal_connect
- (GTK_OBJECT(dialog), "destroy", GTK_SIGNAL_FUNC(gtk_main_quit), NULL);
- #else
- NULL, 0,
- gimp_standard_help_func, "rawphoto",
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- GTK_STOCK_OK, GTK_RESPONSE_OK,
- NULL);
- #endif
- table = gtk_table_new (9, 2, FALSE);
- gtk_container_set_border_width (GTK_CONTAINER(table), 6);
- gtk_box_pack_start
- (GTK_BOX(GTK_DIALOG(dialog)->vbox), table, FALSE, FALSE, 0);
- gtk_widget_show (table);
- for (i=0; i < NCHECK; i++) {
- widget = gtk_check_button_new_with_label
- (_(label[i]));
- gtk_toggle_button_set_active
- (GTK_TOGGLE_BUTTON (widget), cfg.check_val[i]);
- gtk_table_attach
- (GTK_TABLE(table), widget, 0, 2, i, i+1, GTK_FILL, GTK_FILL, 0, 0);
- gtk_signal_connect (GTK_OBJECT (widget), "toggled",
- GTK_SIGNAL_FUNC (gimp_toggle_button_update),
- &cfg.check_val[i]);
- gtk_widget_show (widget);
- }
- for (i=NCHECK; i < NCHECK+2; i++) {
- widget = gtk_label_new (_(label[i]));
- gtk_misc_set_alignment (GTK_MISC (widget), 1.0, 0.5);
- gtk_misc_set_padding (GTK_MISC (widget), 10, 0);
- gtk_table_attach
- (GTK_TABLE(table), widget, 0, 1, i, i+1, GTK_FILL, GTK_FILL, 0, 0);
- gtk_widget_show (widget);
- if (i == NCHECK+1)
- widget = gimp_spin_button_new
- (&adj, cfg.spin_val[i-NCHECK], 0, 9, 1, 9, 1, 1, 0);
- else
- widget = gimp_spin_button_new
- (&adj, cfg.spin_val[i-NCHECK], 0.01, 4.0, 0.01, 0.1, 0.1, 0.1, 2);
- gtk_table_attach
- (GTK_TABLE(table), widget, 1, 2, i, i+1, GTK_FILL, GTK_FILL, 0, 0);
- gtk_signal_connect (GTK_OBJECT (adj), "value_changed",
- GTK_SIGNAL_FUNC (gimp_float_adjustment_update),
- &cfg.spin_val[i-NCHECK]);
- gtk_widget_show (widget);
- }
- gtk_widget_show (dialog);
- #if !GIMP_CHECK_VERSION(1,3,23)
- gtk_main();
- gdk_flush();
- return result;
- #else
- i = gimp_dialog_run (GIMP_DIALOG (dialog));
- gtk_widget_destroy (dialog);
- return i == GTK_RESPONSE_OK;
- #endif
- }
|