1 //
2 // "$Id: Fluid_Image.cxx 7903 2010-11-28 21:06:39Z matt $"
3 //
4 // Pixmap label support for the Fast Light Tool Kit (FLTK).
5 //
6 // Copyright 1998-2010 by Bill Spitzak and others.
7 //
8 // This library is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU Library General Public
10 // License as published by the Free Software Foundation; either
11 // version 2 of the License, or (at your option) any later version.
12 //
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 // Library General Public License for more details.
17 //
18 // You should have received a copy of the GNU Library General Public
19 // License along with this library; if not, write to the Free Software
20 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21 // USA.
22 //
23 // Please report all bugs and problems on the following page:
24 //
25 //     http://www.fltk.org/str.php
26 //
27 
28 #include <FL/Fl.H>
29 #include <FL/Fl_Widget.H>
30 #include "Fl_Type.h"
31 #include "Fluid_Image.h"
32 #include "../src/flstring.h"
33 #include <stdio.h>
34 #include <errno.h>
35 #include <stdlib.h>
36 #include <FL/filename.H>
37 
38 extern void goto_source_dir(); // in fluid.C
39 extern void leave_source_dir(); // in fluid.C
40 
image(Fl_Widget * o)41 void Fluid_Image::image(Fl_Widget *o) {
42   if (o->window() != o) o->image(img);
43 }
44 
deimage(Fl_Widget * o)45 void Fluid_Image::deimage(Fl_Widget *o) {
46   if (o->window() != o) o->deimage(img);
47 }
48 
49 static int pixmap_header_written = 0;
50 static int bitmap_header_written = 0;
51 static int image_header_written = 0;
52 static int jpeg_header_written = 0;
53 
write_static()54 void Fluid_Image::write_static() {
55   if (!img) return;
56   if (img->count() > 1) {
57     // Write Pixmap data...
58     write_c("\n");
59     if (pixmap_header_written != write_number) {
60       write_c("#include <FL/Fl_Pixmap.H>\n");
61       pixmap_header_written = write_number;
62     }
63     write_c("static const char *%s[] = {\n",
64 	    unique_id(this, "idata", fl_filename_name(name()), 0));
65     write_cstring(img->data()[0], strlen(img->data()[0]));
66 
67     int i;
68     int ncolors, chars_per_color;
69     sscanf(img->data()[0], "%*d%*d%d%d", &ncolors, &chars_per_color);
70 
71     if (ncolors < 0) {
72       write_c(",\n");
73       write_cstring(img->data()[1], ncolors * -4);
74       i = 2;
75     } else {
76       for (i = 1; i <= ncolors; i ++) {
77         write_c(",\n");
78         write_cstring(img->data()[i], strlen(img->data()[i]));
79       }
80     }
81     for (; i < img->count(); i ++) {
82       write_c(",\n");
83       write_cstring(img->data()[i], img->w() * chars_per_color);
84     }
85     write_c("\n};\n");
86     write_c("static Fl_Pixmap %s(%s);\n",
87 	    unique_id(this, "image", fl_filename_name(name()), 0),
88 	    unique_id(this, "idata", fl_filename_name(name()), 0));
89   } else if (img->d() == 0) {
90     // Write Bitmap data...
91     write_c("\n");
92     if (bitmap_header_written != write_number) {
93       write_c("#include <FL/Fl_Bitmap.H>\n");
94       bitmap_header_written = write_number;
95     }
96     write_c("static unsigned char %s[] =\n",
97 	    unique_id(this, "idata", fl_filename_name(name()), 0));
98     write_cdata(img->data()[0], ((img->w() + 7) / 8) * img->h());
99     write_c(";\n");
100     write_c("static Fl_Bitmap %s(%s, %d, %d);\n",
101 	    unique_id(this, "image", fl_filename_name(name()), 0),
102 	    unique_id(this, "idata", fl_filename_name(name()), 0),
103 	    img->w(), img->h());
104   } else if (strcmp(fl_filename_ext(name()), ".jpg")==0) {
105     // Write jpeg image data...
106     write_c("\n");
107     if (jpeg_header_written != write_number) {
108       write_c("#include <FL/Fl_JPEG_Image.H>\n");
109       jpeg_header_written = write_number;
110     }
111     write_c("static unsigned char %s[] =\n",
112 	    unique_id(this, "idata", fl_filename_name(name()), 0));
113 
114     FILE *f = fl_fopen(name(), "rb");
115     if (!f) {
116       // message = "Can't include binary file. Can't open";
117     } else {
118       fseek(f, 0, SEEK_END);
119       size_t nData = ftell(f);
120       fseek(f, 0, SEEK_SET);
121       if (nData) {
122         char *data = (char*)calloc(nData, 1);
123         if (fread(data, nData, 1, f)==0) { /* ignore */ }
124         write_cdata(data, nData);
125         free(data);
126       }
127       fclose(f);
128     }
129 
130     write_c(";\n");
131     write_c("static Fl_JPEG_Image %s(\"%s\", %s);\n",
132 	    unique_id(this, "image", fl_filename_name(name()), 0),
133 	    fl_filename_name(name()),
134 	    unique_id(this, "idata", fl_filename_name(name()), 0));
135   } else {
136     // Write image data...
137     write_c("\n");
138     if (image_header_written != write_number) {
139       write_c("#include <FL/Fl_Image.H>\n");
140       image_header_written = write_number;
141     }
142     write_c("static unsigned char %s[] =\n",
143 	    unique_id(this, "idata", fl_filename_name(name()), 0));
144     write_cdata(img->data()[0], (img->w() * img->d() + img->ld()) * img->h());
145     write_c(";\n");
146     write_c("static Fl_RGB_Image %s(%s, %d, %d, %d, %d);\n",
147 	    unique_id(this, "image", fl_filename_name(name()), 0),
148 	    unique_id(this, "idata", fl_filename_name(name()), 0),
149 	    img->w(), img->h(), img->d(), img->ld());
150   }
151 }
152 
write_code(const char * var,int inactive)153 void Fluid_Image::write_code(const char *var, int inactive) {
154   if (!img) return;
155   write_c("%s%s->%s(%s);\n", indent(), var, inactive ? "deimage" : "image",
156 	  unique_id(this, "image", fl_filename_name(name()), 0));
157 }
158 
159 
160 ////////////////////////////////////////////////////////////////
161 
162 static Fluid_Image** images = 0; // sorted list
163 static int numimages = 0;
164 static int tablesize = 0;
165 
find(const char * iname)166 Fluid_Image* Fluid_Image::find(const char *iname) {
167   if (!iname || !*iname) return 0;
168 
169   // first search to see if it exists already:
170   int a = 0;
171   int b = numimages;
172   while (a < b) {
173     int c = (a+b)/2;
174     int i = strcmp(iname,images[c]->name_);
175     if (i < 0) b = c;
176     else if (i > 0) a = c+1;
177     else return images[c];
178   }
179 
180   // no, so now see if the file exists:
181 
182   goto_source_dir();
183   FILE *f = fl_fopen(iname,"rb");
184   if (!f) {
185     read_error("%s : %s",iname,strerror(errno));
186     leave_source_dir();
187     return 0;
188   }
189   fclose(f);
190 
191   Fluid_Image *ret = new Fluid_Image(iname);
192 
193   if (!ret->img || !ret->img->w() || !ret->img->h()) {
194     delete ret;
195     ret = 0;
196     read_error("%s : unrecognized image format", iname);
197   }
198   leave_source_dir();
199   if (!ret) return 0;
200 
201   // make a new entry in the table:
202   numimages++;
203   if (numimages > tablesize) {
204     tablesize = tablesize ? 2*tablesize : 16;
205     if (images) images = (Fluid_Image**)realloc(images, tablesize*sizeof(Fluid_Image*));
206     else images = (Fluid_Image**)malloc(tablesize*sizeof(Fluid_Image*));
207   }
208   for (b = numimages-1; b > a; b--) images[b] = images[b-1];
209   images[a] = ret;
210 
211   return ret;
212 }
213 
Fluid_Image(const char * iname)214 Fluid_Image::Fluid_Image(const char *iname) {
215   name_ = strdup(iname);
216   written = 0;
217   refcount = 0;
218   img = Fl_Shared_Image::get(iname);
219 }
220 
increment()221 void Fluid_Image::increment() {
222   ++refcount;
223 }
224 
decrement()225 void Fluid_Image::decrement() {
226   --refcount;
227   if (refcount > 0) return;
228   delete this;
229 }
230 
~Fluid_Image()231 Fluid_Image::~Fluid_Image() {
232   int a;
233   if (images) {
234     for (a = 0;; a++) if (images[a] == this) break;
235     numimages--;
236     for (; a < numimages; a++) images[a] = images[a+1];
237   }
238   if (img) img->release();
239   free((void*)name_);
240 }
241 
242 ////////////////////////////////////////////////////////////////
243 
244 #include <FL/Fl_File_Chooser.H>
245 
246 const char *ui_find_image_name;
ui_find_image(const char * oldname)247 Fluid_Image *ui_find_image(const char *oldname) {
248   goto_source_dir();
249   fl_file_chooser_ok_label("Use Image");
250   const char *name = fl_file_chooser("Image?","Image Files (*.{bm,bmp,gif,jpg,pbm,pgm,png,ppm,xbm,xpm})",oldname,1);
251   fl_file_chooser_ok_label(NULL);
252   ui_find_image_name = name;
253   Fluid_Image *ret = (name && *name) ? Fluid_Image::find(name) : 0;
254   leave_source_dir();
255   return ret;
256 }
257 
258 
259 //
260 // End of "$Id: Fluid_Image.cxx 7903 2010-11-28 21:06:39Z matt $".
261 //
262