Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
graphics
dcraw
rawphoto.c
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File rawphoto.c of Package dcraw
/* 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 }
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor