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