png_im_export.C

Go to the documentation of this file.
00001 /* Gnome gxsm - Gnome X Scanning Microscopy
00002  * universal STM/AFM/SARLS/SPALEED/... controlling and
00003  * data analysis software
00004  *
00005  * Gxsm Plugin Name: png_im_export.C
00006  * ========================================
00007  * 
00008  * Copyright (C) 1999 The Free Software Foundation
00009  *
00010  * Authors: Percy Zahl <zahl@fkp.uni-hannover.de>
00011  * additional features: Andreas Klust <klust@fkp.uni-hannover.de>
00012  *
00013  * This program is free software; you can redistribute it and/or modify
00014  * it under the terms of the GNU General Public License as published by
00015  * the Free Software Foundation; either version 2 of the License, or
00016  * (at your option) any later version.
00017  *
00018  * This program is distributed in the hope that it will be useful,
00019  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00020  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00021  * GNU General Public License for more details.
00022  *
00023  * You should have received a copy of the GNU General Public License
00024  * along with this program; if not, write to the Free Software
00025  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
00026  */
00027 
00028 /* Please do not change the Begin/End lines of this comment section!
00029  * this is a LaTeX style section used for auto generation of the PlugIn Manual 
00030  * Chapter. Add a complete PlugIn documentation inbetween the Begin/End marks!
00031  * --------------------------------------------------------------------------------
00032 % BeginPlugInDocuSection
00033 % PlugInDocuCaption: PNG image Import/Export
00034 % PlugInName: png_Im_Export
00035 % PlugInAuthor: Percy Zahl
00036 % PlugInAuthorEmail: zahl@users.sf.net
00037 % PlugInMenuPath: File/Import/PNG
00038 
00039 % PlugInDescription
00040 The \GxsmEmph{png\_im\_export} plug-in allows reading and writing of images using the
00041 Portabe Network Graphics (PNG) image format. 
00042 
00043 The currently set palette is used if non is used or available a grey
00044 scale image is generated. The currect set view mode
00045 (Direct/Quick/...) is used for automatic data transformation. The resulting image will
00046 appear like the active view but it has the size of the original scan (no zoom/quench applies).
00047 
00048 A special feature: If the scan has type "RGBA" (4 layers) the raw data of the channels is written
00049 without any transfornation or scaling to the PNG file in RGB mode.
00050 
00051 % PlugInUsage
00052 The plug-in is called by \GxsmMenu{File/Import/PNG} and \GxsmMenu{File/Export/PNG}.
00053 
00054 %% OptPlugInKnownBugs
00055 
00056 % OptPlugInRefs
00057 pnglib documentation: \GxsmWebLink{www.libpng.org/pub/png/libpng-manual.html}
00058 
00059 
00060 % EndPlugInDocuSection
00061  * -------------------------------------------------------------------------------- 
00062  */
00063 
00064 #include <gtk/gtk.h>
00065 #include "config.h"
00066 #include "gxsm/plugin.h"
00067 #include "gxsm/dataio.h"
00068 #include "gxsm/action_id.h"
00069 #include "gxsm/util.h"
00070 #include "gxsm/xsmtypes.h"
00071 #include "gxsm/glbvars.h"
00072 
00073 // custom includes go here
00074 // -- START EDIT --
00075 #include "png.h"        /* libpng header; includes zlib.h */
00076 #include "readpng.h"    /* typedefs, common macros, public prototypes */
00077 #include "writepng.h"    /* typedefs, common macros, public prototypes */
00078 // -- END EDIT --
00079 
00080 // enable std namespace
00081 using namespace std;
00082 
00083 // Plugin Prototypes
00084 static void png_im_export_init (void);
00085 static void png_im_export_query (void);
00086 static void png_im_export_about (void);
00087 static void png_im_export_configure (void);
00088 static void png_im_export_cleanup (void);
00089 
00090 static void png_im_export_filecheck_load_callback (gpointer data );
00091 static void png_im_export_filecheck_save_callback (gpointer data );
00092 
00093 static void png_im_export_import_callback (GtkWidget *w, void *data);
00094 static void png_im_export_export_callback (GtkWidget *w, void *data);
00095 
00096 // Fill in the GxsmPlugin Description here
00097 GxsmPlugin png_im_export_pi = {
00098   NULL,                   // filled in and used by Gxsm, don't touch !
00099   NULL,                   // filled in and used by Gxsm, don't touch !
00100   0,                      // filled in and used by Gxsm, don't touch !
00101   NULL,                   // The Gxsm-App Class Ref.pointer (called "gapp" in Gxsm) is 
00102                           // filled in here by Gxsm on Plugin load, 
00103                           // just after init() is called !!!
00104 // -- START EDIT --
00105   "PNG-ImExport",            // PlugIn name
00106   NULL,                   // PlugIn's Categorie, set to NULL for all, I just don't want this always to be loaded!
00107   // Description, is shown by PluginViewer (Plugin: listplugin, Tools->Plugin Details)
00108   "Im/Export PNG images.",
00109   "Percy Zahl",
00110   N_("_File/_Import/,_File/_Export/"), // sep. im/export menuentry path by comma!
00111   N_("PNG,PNG"), // menu entry (same for both)
00112   N_("PNG import,PNG export"), // short help for menu entry
00113   N_("PNG import and export filter."), // info
00114 // -- END EDIT --
00115   NULL,          // error msg, plugin may put error status msg here later
00116   NULL,          // Plugin Status, managed by Gxsm, plugin may manipulate it too
00117   png_im_export_init,
00118   png_im_export_query,
00119   // about-function, can be "NULL"
00120   // can be called by "Plugin Details"
00121   png_im_export_about,
00122   // configure-function, can be "NULL"
00123   // can be called by "Plugin Details"
00124   png_im_export_configure,
00125   // run-function, can be "NULL", if non-Zero and no query defined, 
00126   // it is called on menupath->"plugin"
00127   NULL,
00128   // cleanup-function, can be "NULL"
00129   // called if present at plugin removeal
00130   png_im_export_cleanup
00131 };
00132 
00133 // Text used in Aboutbox, please update!!
00134 static const char *about_text = N_("This GXSM plugin allows im- and export of PNG image data files");
00135 
00136 static const char *file_mask = "*.png";
00137 
00138 // Symbol "get_gxsm_plugin_info" is resolved by dlsym from Gxsm, used to get Plugin's info!! 
00139 // Essential Plugin Function!!
00140 GxsmPlugin *get_gxsm_plugin_info ( void ){ 
00141   png_im_export_pi.description = g_strdup_printf(N_("Gxsm im_export plugin %s"), VERSION);
00142   return &png_im_export_pi; 
00143 }
00144 
00145 // Query Function, installs Plugin's in File/Import and Export Menupaths!
00146 // ----------------------------------------------------------------------
00147 // Import Menupath is "File/Import/PNG"
00148 // Export Menupath is "File/Export/PNGt"
00149 // ----------------------------------------------------------------------
00150 
00151 static void png_im_export_query(void)
00152 {
00153         gchar **path  = g_strsplit (png_im_export_pi.menupath, ",", 2);
00154         gchar **entry = g_strsplit (png_im_export_pi.menuentry, ",", 2);
00155         gchar **help  = g_strsplit (png_im_export_pi.help, ",", 2);
00156 
00157         static GnomeUIInfo menuinfo_i[] = { 
00158                 { GNOME_APP_UI_ITEM, NULL, NULL,
00159                   NULL, NULL,
00160                   NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_OPEN,
00161                   0, GDK_CONTROL_MASK, NULL },
00162                 GNOMEUIINFO_END
00163         };
00164         menuinfo_i[0].label  = entry[0];
00165         menuinfo_i[0].hint   = help[0];
00166         menuinfo_i[0].moreinfo  = (gpointer) png_im_export_import_callback; 
00167         menuinfo_i[0].user_data = png_im_export_pi.name;
00168 
00169         gnome_app_insert_menus (
00170                 GNOME_APP(png_im_export_pi.app->getApp()), 
00171                 path[0], 
00172                 menuinfo_i
00173                 );
00174         
00175 
00176         static GnomeUIInfo menuinfo_e[] = { 
00177                 { GNOME_APP_UI_ITEM, NULL, NULL,
00178                   NULL, NULL,
00179                   NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_SAVE,
00180                   0, GDK_CONTROL_MASK, NULL },
00181                 GNOMEUIINFO_END
00182         };
00183         menuinfo_e[0].label  = entry[1];
00184         menuinfo_e[0].hint   = help[1];
00185         menuinfo_e[0].moreinfo  = (gpointer) png_im_export_export_callback; 
00186         menuinfo_e[0].user_data = png_im_export_pi.name;
00187 
00188         gnome_app_insert_menus (
00189                 GNOME_APP(png_im_export_pi.app->getApp()), 
00190                 path[1],
00191                 menuinfo_e
00192                 );
00193 
00194         if(png_im_export_pi.status) g_free(png_im_export_pi.status); 
00195         png_im_export_pi.status = g_strconcat (
00196                 N_("Plugin query has attached "),
00197                 png_im_export_pi.name, 
00198                 N_(": File IO Filters are ready to use."),
00199                 NULL);
00200         
00201         // clean up
00202         g_strfreev (path);
00203         g_strfreev (entry);
00204         g_strfreev (help);
00205 
00206         // register this plugins filecheck functions with Gxsm now!
00207         // This allows Gxsm to check files from DnD, open, 
00208         // and cmdline sources against all known formats automatically - no explicit im/export is necessary.
00209         png_im_export_pi.app->ConnectPluginToLoadFileEvent (png_im_export_filecheck_load_callback);
00210         png_im_export_pi.app->ConnectPluginToSaveFileEvent (png_im_export_filecheck_save_callback);
00211 }
00212 
00213 
00214 // 5.) Start here with the plugins code, vars def., etc.... here.
00215 // ----------------------------------------------------------------------
00216 //
00217 
00218 
00219 // init-Function
00220 static void png_im_export_init(void)
00221 {
00222         PI_DEBUG (DBG_L2, png_im_export_pi.name << " Plugin Init");
00223 }
00224 
00225 // about-Function
00226 static void png_im_export_about(void)
00227 {
00228         const gchar *authors[] = { png_im_export_pi.authors, NULL};
00229         gtk_widget_show(gnome_about_new ( png_im_export_pi.name,
00230                                           VERSION,
00231                                           N_("(C) 2001 the Free Software Foundation"),
00232                                           about_text,
00233                                           authors,
00234                                           NULL, NULL, NULL
00235                                           ));
00236 }
00237 
00238 // configure-Function
00239 static void png_im_export_configure(void)
00240 {
00241         if(png_im_export_pi.app)
00242                 png_im_export_pi.app->message("PNG im_export Plugin Configuration");
00243 }
00244 
00245 // cleanup-Function, remove all "custom" menu entrys here!
00246 static void png_im_export_cleanup(void)
00247 {
00248         gchar **path  = g_strsplit (png_im_export_pi.menupath, ",", 2);
00249         gchar **entry = g_strsplit (png_im_export_pi.menuentry, ",", 2);
00250 
00251         gchar *tmp = g_strconcat (path[0], entry[0], NULL);
00252         gnome_app_remove_menus (GNOME_APP (png_im_export_pi.app->getApp()), tmp, 1);
00253         g_free (tmp);
00254 
00255         tmp = g_strconcat (path[1], entry[1], NULL);
00256         gnome_app_remove_menus (GNOME_APP (png_im_export_pi.app->getApp()), tmp, 1);
00257         g_free (tmp);
00258 
00259         g_strfreev (path);
00260         g_strfreev (entry);
00261 
00262         PI_DEBUG (DBG_L2, "Plugin Cleanup done.");
00263 }
00264 
00265 
00266 // make a new derivate of the base class "Dataio"
00267 class PNG_ImExportFile : public Dataio{
00268 public:
00269         PNG_ImExportFile(Scan *s, const char *n) : Dataio(s,n){; };
00270         virtual FIO_STATUS Read();
00271         virtual FIO_STATUS Write();
00272 private:
00273         FIO_STATUS import_data(const char *fname); 
00274 };
00275 
00276 FIO_STATUS PNG_ImExportFile::Read(){
00277         FIO_STATUS ret;
00278         gchar *fname=NULL;
00279 
00280         PI_DEBUG (DBG_L2, "reading");
00281 
00282         fname = (gchar*)name;
00283 
00284         // name should have at least 4 chars: ".ext"
00285         if (fname == NULL || strlen(fname) < 4)
00286                 return status=FIO_NOT_RESPONSIBLE_FOR_THAT_FILE;
00287 
00288         if (strncasecmp(fname+strlen(fname)-4,".png",4)){
00289                 return status=FIO_NOT_RESPONSIBLE_FOR_THAT_FILE;
00290         }
00291  
00292         // check for file exists and is OK !
00293         // else open File Dlg
00294         ifstream f;
00295         f.open(fname, ios::in);
00296         if(!f.good()){
00297                 PI_DEBUG (DBG_L2, "Error at file open. File not good/readable.");
00298                 return status=FIO_OPEN_ERR;
00299         }
00300         f.close();
00301 
00302         // Check all known File Types:
00303         if ((ret=import_data (fname)) !=  FIO_NOT_RESPONSIBLE_FOR_THAT_FILE)
00304                 return ret;
00305 
00306         return  status=FIO_NOT_RESPONSIBLE_FOR_THAT_FILE;
00307 }
00308 
00309 FIO_STATUS PNG_ImExportFile::import_data(const char *fname){
00310         FILE *infile;
00311         double display_exponent;
00312         ulg image_width, image_height, image_rowbytes;
00313         int image_channels;
00314         int rc;
00315         
00316         gboolean byteswap = FALSE;
00317 
00318         // Checking resposibility for this file as good as possible, use
00319         // extension(s) (most simple), magic numbers, etc.
00320         ifstream f;
00321         GString *FileList=NULL;
00322 
00323         cout << "PNG::: importing from >" << fname << "<" << endl;
00324         PI_DEBUG (DBG_L2, "importing from >" << fname << "<");
00325 
00326         if (!(infile = fopen(fname, "rb")))
00327                 return status=FIO_OPEN_ERR;
00328 
00329         cout << "PNG::: reset to defaults" << endl;
00330 
00331         // reset old scan fully to defaults
00332         SCAN_DATA scan_template;
00333 //      scan->data.CpUnits (scan_template);
00334         scan->data.GetScan_Param (scan_template);
00335 //      scan->data.GetLayer_Param (scan_template);
00336         scan->data.GetUser_Info (scan_template);
00337 //      scan->data.GetDSP_Param (scan_template);
00338         scan->data.GetDisplay_Param (scan_template);
00339 
00340         cout << "PNG::: readpng" << endl;
00341         // now start importing -----------------------------------------
00342         if ((rc = readpng_init(infile, &image_width, &image_height)) != 0) {
00343                 gchar *error_msg = NULL;
00344                 switch (rc) {
00345                 case 1:
00346                         PI_DEBUG (DBG_L2, "[" << fname << "] is not a PNG file: incorrect signature");
00347                         error_msg = g_strdup_printf (N_("[%s] is not a PNG file: incorrect signature"),
00348                                                      fname);
00349                         break;
00350                 case 2:
00351                         PI_DEBUG (DBG_L2, "[" << fname << "] has bad IHDR (libpng longjmp)");
00352                         error_msg = g_strdup_printf (N_("[%s] has bad IHDR (libpng longjmp)"),
00353                                                      fname);
00354                         break;
00355                 case 4:
00356                         PI_DEBUG (DBG_L2, "insufficient memory");
00357                         error_msg = g_strdup_printf (N_("insufficient memory"));
00358                         break;
00359                 default:
00360                         PI_DEBUG (DBG_L2, "unknown readpng_init() error");
00361                         error_msg = g_strdup_printf (N_("unknown readpng_init() error"));
00362                         break;
00363                 }
00364    
00365                 cout << error_msg << endl;
00366         
00367                 if (error_msg && (rc > 1 || strstr (fname, ".png"))){
00368                         GtkWidget *dialog = gtk_message_dialog_new (NULL,
00369                                                                     GTK_DIALOG_DESTROY_WITH_PARENT,
00370                                                                     GTK_MESSAGE_INFO,
00371                                                                     GTK_BUTTONS_OK,
00372                                                                     error_msg);
00373                         gtk_dialog_run (GTK_DIALOG (dialog));
00374                         g_signal_connect_swapped (GTK_OBJECT (dialog), "response",
00375                                                   G_CALLBACK (gtk_widget_destroy),
00376                                                   GTK_OBJECT (dialog));
00377                 }
00378                 g_free (error_msg);
00379                 fclose (infile);
00380                 return FIO_NOT_RESPONSIBLE_FOR_THAT_FILE;
00381         }
00382 
00383         // update as much as we get...
00384         time_t t; // Scan - Startzeit eintragen 
00385         time(&t);
00386         gchar *tmp = g_strconcat ((ctime(&t)), " (Imported)", NULL); scan->data.ui.SetDateOfScan (tmp); g_free (tmp);
00387         scan->data.ui.SetName (name);
00388         scan->data.ui.SetOriginalName (name);
00389         scan->data.ui.SetType ("PNG color image");
00390         scan->data.ui.SetUser ("nobody");
00391 
00392         FileList = g_string_new ("Imported by GXSM from PNG.\n");
00393         g_string_sprintfa (FileList, "Original Filename: %s\n", name);
00394         g_string_append (FileList, "blaaa:\n");
00395         scan->data.ui.SetComment (FileList->str);
00396         g_string_free(FileList, TRUE); 
00397         FileList=NULL;
00398 
00399 
00400         XsmRescourceManager xrm("PNG_IM_EXPORT");
00401         xrm.Get ("AngPerPixelX", &scan->data.s.dx, "1.0"),
00402         xrm.Get ("AngPerPixelY", &scan->data.s.dy, "1.0"),
00403 
00404         scan->data.s.ntimes = 1;
00405         scan->data.s.nvalues = 4;
00406         scan->data.s.nx = image_width;
00407         scan->data.s.ny = image_height;
00408 //      scan->data.s.dx = 1;
00409 //      scan->data.s.dy = 1;
00410         scan->data.s.dz = 1;
00411         scan->data.s.rx = scan->data.s.nx*scan->data.s.dx;
00412         scan->data.s.ry = scan->data.s.ny*scan->data.s.dy;
00413         scan->data.s.rz = 256.0;
00414         scan->data.s.x0 = 0;
00415         scan->data.s.y0 = 0;
00416         scan->data.s.alpha = 0.;
00417         scan->data.display.bright = 0.;
00418         scan->data.display.vrange_z = 256.;
00419         scan->data.display.voffset_z = 0.;
00420         
00421         scan->mem2d->Resize (scan->data.s.nx, scan->data.s.ny, ZD_RGBA);
00422 
00423         scan->data.orgmode = SCAN_ORG_CENTER;
00424         scan->mem2d->data->MkXLookup (-scan->data.s.rx/2., scan->data.s.rx/2.);
00425         scan->mem2d->data->MkYLookup (-scan->data.s.ry/2., scan->data.s.ry/2.);
00426 
00427         uch *image_data = readpng_get_image(display_exponent, &image_channels, &image_rowbytes);
00428 
00429         uch *src;
00430         ulg lastrow, row;
00431         uch r, g, b, a;
00432         ulg red, green, blue;
00433 
00434         for (lastrow = row = 0;  row < image_height;  ++row) {
00435                 src = image_data + row*image_rowbytes;
00436                 if (image_channels == 3) {
00437                         for (int i = 0; i < image_width; ++i) {
00438                                 red   = *src++;
00439                                 green = *src++;
00440                                 blue  = *src++;
00441                                 scan->mem2d->PutDataPkt ((double)red,   i, row, 0);
00442                                 scan->mem2d->PutDataPkt ((double)green, i, row, 1);
00443                                 scan->mem2d->PutDataPkt ((double)blue,  i, row, 2);
00444                                 scan->mem2d->PutDataPkt (0., i, row, 3);
00445                         }
00446                 } else  /* if (image_channels == 4) */ {
00447                         for (int i = 0; i < image_width; ++i) {
00448                                 r = *src++;
00449                                 g = *src++;
00450                                 b = *src++;
00451                                 a = *src++;
00452                                 scan->mem2d->PutDataPkt ((double)r, i, row, 0);
00453                                 scan->mem2d->PutDataPkt ((double)g, i, row, 1);
00454                                 scan->mem2d->PutDataPkt ((double)b, i, row, 2);
00455                                 scan->mem2d->PutDataPkt ((double)a, i, row, 3);
00456 //                                      alpha_composite(red,   r, a, bg_red);
00457 //                                      alpha_composite(green, g, a, bg_green);
00458 //                                      alpha_composite(blue,  b, a, bg_blue);
00459                         }
00460                 }
00461         }
00462         readpng_cleanup(TRUE);
00463         fclose(infile);
00464         return status=FIO_OK; 
00465 }
00466 
00467 FIO_STATUS PNG_ImExportFile::Write(){
00468         int pcnt=0;
00469         mainprog_info m;
00470         unsigned char **rgb;
00471 
00472         PI_DEBUG (DBG_L2, "writing >" << name << "<");
00473 
00474         if (name == NULL) return FIO_NO_NAME;
00475 
00476         m.gamma   = 1.;
00477         m.width   = scan->data.s.nx;
00478         m.height  = scan->data.s.ny;
00479         m.modtime = time(NULL);
00480         m.infile  = NULL;
00481         if (! (m.outfile = fopen(name, "wb")))
00482                 return status=FIO_OPEN_ERR;
00483 
00484         rgb = new unsigned char* [m.height];
00485         for (int i=0; i<m.height; rgb[i++] = new unsigned char[3*m.width]);
00486 
00487 
00488 
00489         if (scan->mem2d->GetNv() == 4){ // use direct RGB[A] from data
00490                 int k,j;
00491                 for (int i=0; i<m.height; ++i)
00492                         for (k=j=0; j<m.width; ++j){
00493                                 *(rgb[i] + k++) = (unsigned char)scan->mem2d->GetDataPkt (j, i, 0);
00494                                 *(rgb[i] + k++) = (unsigned char)scan->mem2d->GetDataPkt (j, i, 1);
00495                                 *(rgb[i] + k++) = (unsigned char)scan->mem2d->GetDataPkt (j, i, 2);
00496                         }
00497         }else{
00498 
00499                 int k,j;
00500                 int cval;
00501                 ifstream cpal;
00502                 char pline[256];
00503                 int r,g,b,nx,ny;
00504                 double val;
00505                 int ival;
00506                 int maxcol=1024;
00507                 unsigned char tgapal[1024][3];
00508 
00509                 if (gapp->xsm->ZoomFlg & VIEW_PALETTE){
00510                         cpal.open(xsmres.Palette, ios::in);
00511                         PI_DEBUG (DBG_L2, "Using Palette: " << xsmres.Palette );
00512                         if(cpal.good()){
00513                                 cpal.getline(pline, 255);
00514                                 cpal.getline(pline, 255);
00515                                 cpal >> nx >> ny;
00516                                 cpal.getline(pline, 255);
00517                                 cpal.getline(pline, 255);
00518                                 
00519                                 for(maxcol=min(nx, 1024), cval=0; cval<maxcol; ++cval){
00520                                         cpal >> r >> g >> b ;
00521                                         tgapal[cval][0] = r;
00522                                         tgapal[cval][1] = g;
00523                                         tgapal[cval][2] = b;
00524                                 }
00525                                 cpal.close();
00526                         } else {
00527                                 PI_DEBUG (DBG_L2, "Using Palette failed, fallback to greyscale!" );
00528                                 for (maxcol=256, cval=0; cval<maxcol; ++cval)
00529                                         tgapal[cval][2] = tgapal[cval][1] = tgapal[cval][0] = cval * 255 / maxcol; 
00530                         }
00531                 }else{
00532                         PI_DEBUG (DBG_L2, "Using greyscale palette!" );
00533                         for (maxcol=256, cval=0; cval<maxcol; ++cval)
00534                                 tgapal[cval][2] = tgapal[cval][1] = tgapal[cval][0] = cval * 255 / maxcol; 
00535                 }
00536                 PI_DEBUG (DBG_L2, "MaxCol#: " << maxcol );
00537                 PI_DEBUG (DBG_L2, "VFlg:    " << scan->data.display.ViewFlg );
00538 
00539 
00540                 // Set View-Mode Data Range and auto adapt Vcontrast/Bright
00541                 scan->mem2d->SetDataRange(0, maxcol);
00542                 scan->mem2d->AutoDataSkl(NULL, NULL);
00543 
00544                 // use GetDataVMode to use the current set View-Mode (Direct, Quick, ...)
00545                 for (int i=0; i<m.height; ++i)
00546                         for (k=j=0; j<m.width; ++j){
00547                                 val = scan->mem2d->GetDataVMode (j,i);
00548                                 ival = (int)((val >= maxcol ? maxcol-1 : val < 0 ? 0 : val) + .5);
00549 
00550                                 *(rgb[i] + k++) = (unsigned char)tgapal[ival][0];
00551                                 *(rgb[i] + k++) = (unsigned char)tgapal[ival][1];
00552                                 *(rgb[i] + k++) = (unsigned char)tgapal[ival][2];
00553                         }
00554         }
00555 
00556         m.row_pointers = rgb;
00557         m.title  = "GXSM-PNG-ImExport-PlugIn";
00558         m.author = "Percy Zahl";
00559         m.desc   = "GXSM PNG export";
00560         m.copyright = "GPL";
00561         m.email   = "zahl@users.sourceforge.net";
00562         m.url     = "http://gxsm.sf.net";
00563         m.have_bg   = FALSE;
00564         m.have_time = FALSE;
00565         m.have_text = FALSE;
00566         m.pnmtype   = 6; // TYPE_RGB
00567         m.sample_depth = 8;
00568         m.interlaced= FALSE;
00569 
00570         writepng_init (&m);
00571         writepng_encode_image (&m);
00572         writepng_encode_finish (&m);
00573         writepng_cleanup (&m);
00574         fclose (m.outfile);
00575 
00576         for (int i=0; i<m.height; delete[] rgb[i++]);
00577         delete[] rgb;
00578         
00579         // start exporting -------------------------------------------
00580         return status=FIO_OK; 
00581 }
00582 
00583 // Plugin's Notify Cb's, registered to be called on file load/save to check file
00584 // return via filepointer, it is set to Zero or passed as Zero if file has been processed!
00585 // That's all fine, you should just change the Text Stings below...
00586 
00587 
00588 static void png_im_export_filecheck_load_callback (gpointer data ){
00589         gchar **fn = (gchar**)data;
00590         if (*fn){
00591                 PI_DEBUG (DBG_L2, "checking >" << *fn << "<" );
00592 
00593                 Scan *dst = gapp->xsm->GetActiveScan();
00594                 if(!dst){ 
00595                         gapp->xsm->ActivateFreeChannel();
00596                         dst = gapp->xsm->GetActiveScan();
00597                 }
00598                 PNG_ImExportFile fileobj (dst, *fn);
00599 
00600                 FIO_STATUS ret = fileobj.Read(); 
00601                 if (ret != FIO_OK){ 
00602                         // I'am responsible! (But failed)
00603                         if (ret != FIO_NOT_RESPONSIBLE_FOR_THAT_FILE)
00604                                 *fn=NULL;
00605                         // no more data: remove allocated and unused scan now, force!
00606                         gapp->xsm->SetMode(-1, ID_CH_M_OFF, TRUE); 
00607                         PI_DEBUG (DBG_L2, "Read Error " << ((int)ret) );
00608                 }else{
00609                         // got it!
00610                         *fn=NULL;
00611 
00612                         // Now update gxsm main window data fields
00613                         gapp->xsm->ActiveScan->GetDataSet(gapp->xsm->data);
00614                         gapp->spm_update_all();
00615                         dst->draw();
00616                 }
00617         }else{
00618                 PI_DEBUG (DBG_L2, "Skipping" << *fn << "<" );
00619         }
00620 }
00621 
00622 static void png_im_export_filecheck_save_callback (gpointer data ){
00623         gchar **fn = (gchar**)data;
00624         if (*fn){
00625                 Scan *src;
00626                 PI_DEBUG (DBG_L2, "Saving/(checking) >" << *fn << "<" );
00627 
00628                 PNG_ImExportFile fileobj (src = gapp->xsm->GetActiveScan(), *fn);
00629 
00630                 FIO_STATUS ret;
00631                 ret = fileobj.Write(); 
00632 
00633                 if(ret != FIO_OK){
00634                         // I'am responsible! (But failed)
00635                         if (ret != FIO_NOT_RESPONSIBLE_FOR_THAT_FILE)
00636                                 *fn=NULL;
00637                         PI_DEBUG (DBG_L2, "Write Error " << ((int)ret) );
00638                 }else{
00639                         // write done!
00640                         *fn=NULL;
00641                 }
00642         }else{
00643                 PI_DEBUG (DBG_L2, "Skipping >" << *fn << "<" );
00644         }
00645 }
00646 
00647 // Menu callback functions -- usually no need to edit
00648 
00649 static void png_im_export_import_callback(GtkWidget *w, void *data){
00650         gchar **help = g_strsplit (png_im_export_pi.help, ",", 2);
00651         gchar *dlgid = g_strconcat (png_im_export_pi.name, "-import", NULL);
00652         gchar *fn = gapp->file_dialog (help[0], NULL, file_mask, NULL, dlgid);
00653         g_strfreev (help); 
00654         g_free (dlgid);
00655         png_im_export_filecheck_load_callback (&fn );
00656 }
00657 
00658 static void png_im_export_export_callback(GtkWidget *w, void *data){
00659         gchar **help = g_strsplit (png_im_export_pi.help, ",", 2);
00660         gchar *dlgid = g_strconcat (png_im_export_pi.name, "-export", NULL);
00661         gchar *fn = gapp->file_dialog(help[1], NULL, file_mask, NULL, dlgid);
00662         g_strfreev (help); 
00663         g_free (dlgid);
00664         png_im_export_filecheck_save_callback (&fn );
00665 }

Generated on Sat Apr 1 09:04:26 2006 for GXSM by  doxygen 1.4.6