fltk 1.3.0rc3
About: FLTK (Fast Light Tool Kit) is a cross-platform C++ GUI toolkit for UNIX/Linux (X11), Microsoft Windows, and MacOS X. Release candidate.
  SfR Fresh Dox: fltk-1.3.0rc3-source.tar.gz ("inofficial" and yet experimental doxygen-generated source code documentation)  

Fluid_Image.cxx

Go to the documentation of this file.
00001 //
00002 // "$Id: Fluid_Image.cxx 7903 2010-11-28 21:06:39Z matt $"
00003 //
00004 // Pixmap label support for the Fast Light Tool Kit (FLTK).
00005 //
00006 // Copyright 1998-2010 by Bill Spitzak and others.
00007 //
00008 // This library is free software; you can redistribute it and/or
00009 // modify it under the terms of the GNU Library General Public
00010 // License as published by the Free Software Foundation; either
00011 // version 2 of the License, or (at your option) any later version.
00012 //
00013 // This library is distributed in the hope that it will be useful,
00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016 // Library General Public License for more details.
00017 //
00018 // You should have received a copy of the GNU Library General Public
00019 // License along with this library; if not, write to the Free Software
00020 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00021 // USA.
00022 //
00023 // Please report all bugs and problems on the following page:
00024 //
00025 //     http://www.fltk.org/str.php
00026 //
00027 
00028 #include <FL/Fl.H>
00029 #include <FL/Fl_Widget.H>
00030 #include "Fl_Type.h"
00031 #include "Fluid_Image.h"
00032 #include "../src/flstring.h"
00033 #include <stdio.h>
00034 #include <errno.h>
00035 #include <stdlib.h>
00036 #include <FL/filename.H>
00037 
00038 extern void goto_source_dir(); // in fluid.C
00039 extern void leave_source_dir(); // in fluid.C
00040 
00041 void Fluid_Image::image(Fl_Widget *o) {
00042   if (o->window() != o) o->image(img);
00043 }
00044 
00045 void Fluid_Image::deimage(Fl_Widget *o) {
00046   if (o->window() != o) o->deimage(img);
00047 }
00048 
00049 static int pixmap_header_written = 0;
00050 static int bitmap_header_written = 0;
00051 static int image_header_written = 0;
00052 static int jpeg_header_written = 0;
00053 
00054 void Fluid_Image::write_static() {
00055   if (!img) return;
00056   if (img->count() > 1) {
00057     // Write Pixmap data...
00058     write_c("\n");
00059     if (pixmap_header_written != write_number) {
00060       write_c("#include <FL/Fl_Pixmap.H>\n");
00061       pixmap_header_written = write_number;
00062     }
00063     write_c("static const char *%s[] = {\n",
00064             unique_id(this, "idata", fl_filename_name(name()), 0));
00065     write_cstring(img->data()[0], strlen(img->data()[0]));
00066 
00067     int i;
00068     int ncolors, chars_per_color;
00069     sscanf(img->data()[0], "%*d%*d%d%d", &ncolors, &chars_per_color);
00070 
00071     if (ncolors < 0) {
00072       write_c(",\n");
00073       write_cstring(img->data()[1], ncolors * -4);
00074       i = 2;
00075     } else {
00076       for (i = 1; i <= ncolors; i ++) {
00077         write_c(",\n");
00078         write_cstring(img->data()[i], strlen(img->data()[i]));
00079       }
00080     }
00081     for (; i < img->count(); i ++) {
00082       write_c(",\n");
00083       write_cstring(img->data()[i], img->w() * chars_per_color);
00084     }
00085     write_c("\n};\n");
00086     write_c("static Fl_Pixmap %s(%s);\n",
00087             unique_id(this, "image", fl_filename_name(name()), 0),
00088             unique_id(this, "idata", fl_filename_name(name()), 0));
00089   } else if (img->d() == 0) {
00090     // Write Bitmap data...
00091     write_c("\n");
00092     if (bitmap_header_written != write_number) {
00093       write_c("#include <FL/Fl_Bitmap.H>\n");
00094       bitmap_header_written = write_number;
00095     }
00096     write_c("static unsigned char %s[] =\n",
00097             unique_id(this, "idata", fl_filename_name(name()), 0));
00098     write_cdata(img->data()[0], ((img->w() + 7) / 8) * img->h());
00099     write_c(";\n");
00100     write_c("static Fl_Bitmap %s(%s, %d, %d);\n",
00101             unique_id(this, "image", fl_filename_name(name()), 0),
00102             unique_id(this, "idata", fl_filename_name(name()), 0),
00103             img->w(), img->h());
00104   } else if (strcmp(fl_filename_ext(name()), ".jpg")==0) {
00105     // Write jpeg image data...
00106     write_c("\n");
00107     if (jpeg_header_written != write_number) {
00108       write_c("#include <FL/Fl_JPEG_Image.H>\n");
00109       jpeg_header_written = write_number;
00110     }
00111     write_c("static unsigned char %s[] =\n",
00112             unique_id(this, "idata", fl_filename_name(name()), 0));
00113         
00114     FILE *f = fl_fopen(name(), "rb");
00115     if (!f) {
00116       // message = "Can't include binary file. Can't open";
00117     } else {
00118       fseek(f, 0, SEEK_END);
00119       size_t nData = ftell(f);
00120       fseek(f, 0, SEEK_SET);
00121       if (nData) {
00122         char *data = (char*)calloc(nData, 1);
00123         if (fread(data, nData, 1, f)==0) { /* ignore */ }
00124         write_cdata(data, nData);
00125         free(data);
00126       }
00127       fclose(f);
00128     }
00129     
00130     write_c(";\n");
00131     write_c("static Fl_JPEG_Image %s(\"%s\", %s);\n",
00132             unique_id(this, "image", fl_filename_name(name()), 0),
00133             fl_filename_name(name()),
00134             unique_id(this, "idata", fl_filename_name(name()), 0));
00135   } else {
00136     // Write image data...
00137     write_c("\n");
00138     if (image_header_written != write_number) {
00139       write_c("#include <FL/Fl_Image.H>\n");
00140       image_header_written = write_number;
00141     }
00142     write_c("static unsigned char %s[] =\n",
00143             unique_id(this, "idata", fl_filename_name(name()), 0));
00144     write_cdata(img->data()[0], (img->w() * img->d() + img->ld()) * img->h());
00145     write_c(";\n");
00146     write_c("static Fl_RGB_Image %s(%s, %d, %d, %d, %d);\n",
00147             unique_id(this, "image", fl_filename_name(name()), 0),
00148             unique_id(this, "idata", fl_filename_name(name()), 0),
00149             img->w(), img->h(), img->d(), img->ld());
00150   }
00151 }
00152 
00153 void Fluid_Image::write_code(const char *var, int inactive) {
00154   if (!img) return;
00155   write_c("%s%s->%s(%s);\n", indent(), var, inactive ? "deimage" : "image",
00156           unique_id(this, "image", fl_filename_name(name()), 0));
00157 }
00158 
00159 
00161 
00162 static Fluid_Image** images = 0; // sorted list
00163 static int numimages = 0;
00164 static int tablesize = 0;
00165 
00166 Fluid_Image* Fluid_Image::find(const char *iname) {
00167   if (!iname || !*iname) return 0;
00168 
00169   // first search to see if it exists already:
00170   int a = 0;
00171   int b = numimages;
00172   while (a < b) {
00173     int c = (a+b)/2;
00174     int i = strcmp(iname,images[c]->name_);
00175     if (i < 0) b = c;
00176     else if (i > 0) a = c+1;
00177     else return images[c];
00178   }
00179 
00180   // no, so now see if the file exists:
00181 
00182   goto_source_dir();
00183   FILE *f = fl_fopen(iname,"rb");
00184   if (!f) {
00185     read_error("%s : %s",iname,strerror(errno));
00186     leave_source_dir();
00187     return 0;
00188   }
00189   fclose(f);
00190 
00191   Fluid_Image *ret = new Fluid_Image(iname);
00192 
00193   if (!ret->img || !ret->img->w() || !ret->img->h()) {
00194     delete ret;
00195     ret = 0;
00196     read_error("%s : unrecognized image format", iname);
00197   }
00198   leave_source_dir();
00199   if (!ret) return 0;
00200 
00201   // make a new entry in the table:
00202   numimages++;
00203   if (numimages > tablesize) {
00204     tablesize = tablesize ? 2*tablesize : 16;
00205     if (images) images = (Fluid_Image**)realloc(images, tablesize*sizeof(Fluid_Image*));
00206     else images = (Fluid_Image**)malloc(tablesize*sizeof(Fluid_Image*));
00207   }
00208   for (b = numimages-1; b > a; b--) images[b] = images[b-1];
00209   images[a] = ret;
00210 
00211   return ret;
00212 }
00213 
00214 Fluid_Image::Fluid_Image(const char *iname) {
00215   name_ = strdup(iname);
00216   written = 0;
00217   refcount = 0;
00218   img = Fl_Shared_Image::get(iname);
00219 }
00220 
00221 void Fluid_Image::increment() {
00222   ++refcount;
00223 }
00224 
00225 void Fluid_Image::decrement() {
00226   --refcount;
00227   if (refcount > 0) return;
00228   delete this;
00229 }
00230 
00231 Fluid_Image::~Fluid_Image() {
00232   int a;
00233   if (images) {
00234     for (a = 0;; a++) if (images[a] == this) break;
00235     numimages--;
00236     for (; a < numimages; a++) images[a] = images[a+1];
00237   }
00238   if (img) img->release();
00239   free((void*)name_);
00240 }
00241 
00243 
00244 #include <FL/Fl_File_Chooser.H>
00245 
00246 const char *ui_find_image_name;
00247 Fluid_Image *ui_find_image(const char *oldname) {
00248   goto_source_dir();
00249   fl_file_chooser_ok_label("Use Image");
00250   const char *name = fl_file_chooser("Image?","Image Files (*.{bm,bmp,gif,jpg,pbm,pgm,png,ppm,xbm,xpm})",oldname,1);
00251   fl_file_chooser_ok_label(NULL);
00252   ui_find_image_name = name;
00253   Fluid_Image *ret = (name && *name) ? Fluid_Image::find(name) : 0;
00254   leave_source_dir();
00255   return ret;
00256 }
00257 
00258 
00259 //
00260 // End of "$Id: Fluid_Image.cxx 7903 2010-11-28 21:06:39Z matt $".
00261 //