1 /********************************************************************************
2 *                                                                               *
3 *                            I c o n   S o u r c e                              *
4 *                                                                               *
5 *********************************************************************************
6 * Copyright (C) 2005,2006 by Jeroen van der Zijp.   All Rights Reserved.        *
7 *********************************************************************************
8 * This library is free software; you can redistribute it and/or                 *
9 * modify it under the terms of the GNU Lesser General Public                    *
10 * License as published by the Free Software Foundation; either                  *
11 * version 2.1 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 * Lesser General Public License for more details.                               *
17 *                                                                               *
18 * You should have received a copy of the GNU Lesser 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  USA.    *
21 *********************************************************************************
22 * $Id: FXIconSource.cpp 3297 2015-12-14 20:30:04Z arthurcnorman $                    *
23 ********************************************************************************/
24 #include "xincs.h"
25 #include "fxver.h"
26 #include "fxdefs.h"
27 #include "FXHash.h"
28 #include "FXThread.h"
29 #include "FXStream.h"
30 #include "FXFile.h"
31 #include "FXFileStream.h"
32 #include "FXMemoryStream.h"
33 #include "FXString.h"
34 #include "FXSize.h"
35 #include "FXPoint.h"
36 #include "FXRectangle.h"
37 #include "FXPath.h"
38 #include "FXSettings.h"
39 #include "FXRegistry.h"
40 #include "FXApp.h"
41 #include "FXIcon.h"
42 #include "FXImage.h"
43 #include "FXIconSource.h"
44 
45 // Built-in icon formats
46 #include "FXBMPIcon.h"
47 #include "FXGIFIcon.h"
48 #include "FXICOIcon.h"
49 #include "FXIFFIcon.h"
50 #include "FXPCXIcon.h"
51 #include "FXPPMIcon.h"
52 #include "FXRASIcon.h"
53 #include "FXRGBIcon.h"
54 #include "FXTGAIcon.h"
55 #include "FXXBMIcon.h"
56 #include "FXXPMIcon.h"
57 
58 // Built-in image formats
59 #include "FXBMPImage.h"
60 #include "FXGIFImage.h"
61 #include "FXICOImage.h"
62 #include "FXIFFImage.h"
63 #include "FXPCXImage.h"
64 #include "FXPPMImage.h"
65 #include "FXRASImage.h"
66 #include "FXRGBImage.h"
67 #include "FXTGAImage.h"
68 #include "FXXBMImage.h"
69 #include "FXXPMImage.h"
70 
71 // Formats requiring external libraries
72 #ifndef CORE_IMAGE_FORMATS
73 #ifdef HAVE_JPEG_H
74 #include "FXJPGIcon.h"
75 #include "FXJPGImage.h"
76 #endif
77 #ifdef HAVE_PNG_H
78 #include "FXPNGIcon.h"
79 #include "FXPNGImage.h"
80 #endif
81 #ifdef HAVE_TIFF_H
82 #include "FXTIFIcon.h"
83 #include "FXTIFImage.h"
84 #endif
85 #endif
86 
87 
88 /*
89   Notes:
90   - Either load an icon from a file, or load from already open stream.
91   - Future versions will take advantage of the new fxcheckXXX() functions
92     to predicates to determine from the data itself what the type is;
93     currently this is quite unreliable due to more extensive analysis
94     needed of the image file format recognition.
95 */
96 
97 
98 using namespace FX;
99 
100 /*******************************************************************************/
101 
102 namespace FX {
103 
104 
105 FXIMPLEMENT(FXIconSource,FXObject,NULL,0)
106 
107 
108 // Initialize icon source
FXIconSource(FXApp * a)109 FXIconSource::FXIconSource(FXApp* a):app(a){
110   FXTRACE((100,"FXIconSource::FXIconSource\n"));
111   }
112 
113 
114 // Scale image or icon to size
scaleToSize(FXImage * image,FXint size,FXint qual) const115 FXImage* FXIconSource::scaleToSize(FXImage *image,FXint size,FXint qual) const {
116   if(image){
117     if((image->getWidth()>size) || (image->getHeight()>size)){
118       if(image->getWidth()>image->getHeight()){
119         image->scale(size,(size*image->getHeight())/image->getWidth(),qual);
120         }
121       else{
122         image->scale((size*image->getWidth())/image->getHeight(),size,qual);
123         }
124       }
125     }
126   return image;
127   }
128 
129 
130 // Load from file
loadIconFile(const FXString & filename,const FXString & type) const131 FXIcon *FXIconSource::loadIconFile(const FXString& filename,const FXString& type) const {
132   FXIcon *icon=NULL;
133   FXTRACE((150,"FXIconSource loadIcon(%s)\n",filename.text()));
134   if(!filename.empty()){
135     FXFileStream store;
136     if(store.open(filename,FXStreamLoad,65536)){
137       if(type.empty()){
138         icon=loadIconStream(store,FXPath::extension(filename));
139         }
140       else{
141         icon=loadIconStream(store,type);
142         }
143       store.close();
144       }
145     }
146   return icon;
147   }
148 
149 
150 // Load from data array
loadIconData(const void * pixels,const FXString & type) const151 FXIcon *FXIconSource::loadIconData(const void *pixels,const FXString& type) const {
152   FXIcon *icon=NULL;
153   if(pixels){
154     FXMemoryStream store;
155     store.open(FXStreamLoad,(FXuchar*)pixels);
156     icon=loadIconStream(store,type);
157     store.close();
158     }
159   return icon;
160   }
161 
162 
163 // Load from already open stream
loadIconStream(FXStream & store,const FXString & type) const164 FXIcon *FXIconSource::loadIconStream(FXStream& store,const FXString& type) const {
165   FXIcon *icon=NULL;
166   if(comparecase(FXBMPIcon::fileExt,type)==0){
167     icon=new FXBMPIcon(app);
168     }
169   else if(comparecase(FXGIFIcon::fileExt,type)==0){
170     icon=new FXGIFIcon(app);
171     }
172   else if(comparecase(FXICOIcon::fileExt,type)==0 || comparecase("cur",type)==0){
173     icon=new FXICOIcon(app);
174     }
175   else if(comparecase(FXIFFIcon::fileExt,type)==0 || comparecase("lbm",type)==0){
176     icon=new FXIFFIcon(app);
177     }
178   else if(comparecase(FXPCXIcon::fileExt,type)==0){
179     icon=new FXPCXIcon(app);
180     }
181   else if(comparecase(FXPPMIcon::fileExt,type)==0 || comparecase("pbm",type)==0 || comparecase("pgm",type)==0 || comparecase("pnm",type)==0){
182     icon=new FXPPMIcon(app);
183     }
184   else if(comparecase(FXRASIcon::fileExt,type)==0){
185     icon=new FXRASIcon(app);
186     }
187   else if(comparecase(FXRGBIcon::fileExt,type)==0){
188     icon=new FXRGBIcon(app);
189     }
190   else if(comparecase(FXTGAIcon::fileExt,type)==0){
191     icon=new FXTGAIcon(app);
192     }
193   else if(comparecase(FXXBMIcon::fileExt,type)==0){
194     icon=new FXXBMIcon(app);
195     }
196   else if(comparecase(FXXPMIcon::fileExt,type)==0){
197     icon=new FXXPMIcon(app);
198     }
199 #ifndef CORE_IMAGE_FORMATS
200 #ifdef HAVE_JPEG_H
201   else if(comparecase(FXJPGIcon::fileExt,type)==0 || comparecase("jpeg",type)==0){
202     icon=new FXJPGIcon(app);
203     }
204 #endif
205 #ifdef HAVE_PNG_H
206   else if(comparecase(FXPNGIcon::fileExt,type)==0){
207     icon=new FXPNGIcon(app);
208     }
209 #endif
210 #ifdef HAVE_TIFF_H
211   else if(comparecase(FXTIFIcon::fileExt,type)==0 || comparecase("tiff",type)==0){
212     icon=new FXTIFIcon(app);
213     }
214 #endif
215 #endif
216   if(icon){
217     if(icon->loadPixels(store)) return icon;
218     delete icon;
219     }
220   return NULL;
221   }
222 
223 
224 // Load from file
loadImageFile(const FXString & filename,const FXString & type) const225 FXImage *FXIconSource::loadImageFile(const FXString& filename,const FXString& type) const {
226   FXImage *image=NULL;
227   FXTRACE((150,"FXIconSource loadImage(%s)\n",filename.text()));
228   if(!filename.empty()){
229     FXFileStream store;
230     if(store.open(filename,FXStreamLoad,65536)){
231       if(type.empty()){
232         image=loadImageStream(store,FXPath::extension(filename));
233         }
234       else{
235         image=loadImageStream(store,type);
236         }
237       store.close();
238       }
239     }
240   return image;
241   }
242 
243 
244 // Load from data array
loadImageData(const void * pixels,const FXString & type) const245 FXImage *FXIconSource::loadImageData(const void *pixels,const FXString& type) const {
246   FXImage *image=NULL;
247   if(pixels){
248     FXMemoryStream store;
249     store.open(FXStreamLoad,(FXuchar*)pixels);
250     image=loadImageStream(store,type);
251     store.close();
252     }
253   return image;
254   }
255 
256 
257 // Load from already open stream
loadImageStream(FXStream & store,const FXString & type) const258 FXImage *FXIconSource::loadImageStream(FXStream& store,const FXString& type) const {
259   FXImage *image=NULL;
260   if(comparecase(FXBMPImage::fileExt,type)==0){
261     image=new FXBMPImage(app);
262     }
263   else if(comparecase(FXGIFImage::fileExt,type)==0){
264     image=new FXGIFImage(app);
265     }
266   else if(comparecase(FXICOImage::fileExt,type)==0 || comparecase("cur",type)==0){
267     image=new FXICOImage(app);
268     }
269   else if(comparecase(FXIFFImage::fileExt,type)==0 || comparecase("lbm",type)==0){
270     image=new FXIFFImage(app);
271     }
272   else if(comparecase(FXPCXImage::fileExt,type)==0){
273     image=new FXPCXImage(app);
274     }
275   else if(comparecase(FXPPMImage::fileExt,type)==0 || comparecase("pbm",type)==0 || comparecase("pgm",type)==0 || comparecase("pnm",type)==0){
276     image=new FXPPMImage(app);
277     }
278   else if(comparecase(FXRASImage::fileExt,type)==0){
279     image=new FXRASImage(app);
280     }
281   else if(comparecase(FXRGBImage::fileExt,type)==0){
282     image=new FXRGBImage(app);
283     }
284   else if(comparecase(FXTGAImage::fileExt,type)==0){
285     image=new FXTGAImage(app);
286     }
287   else if(comparecase(FXXBMImage::fileExt,type)==0){
288     image=new FXXBMImage(app);
289     }
290   else if(comparecase(FXXPMImage::fileExt,type)==0){
291     image=new FXXPMImage(app);
292     }
293 #ifndef CORE_IMAGE_FORMATS
294 #ifdef HAVE_JPEG_H
295   else if(comparecase(FXJPGImage::fileExt,type)==0 || comparecase("jpeg",type)==0){
296     image=new FXJPGImage(app);
297     }
298 #endif
299 #ifdef HAVE_PNG_H
300   else if(comparecase(FXPNGImage::fileExt,type)==0){
301     image=new FXPNGImage(app);
302     }
303 #endif
304 #ifdef HAVE_TIFF_H
305   else if(comparecase(FXTIFImage::fileExt,type)==0 || comparecase("tiff",type)==0){
306     image=new FXTIFImage(app);
307     }
308 #endif
309 #endif
310   if(image){
311     if(image->loadPixels(store)) return image;
312     delete image;
313     }
314   return NULL;
315   }
316 
317 
318 // Load icon and scale it such that its dimensions does not exceed given size
loadScaledIconFile(const FXString & filename,FXint size,FXint qual,const FXString & type) const319 FXIcon *FXIconSource::loadScaledIconFile(const FXString& filename,FXint size,FXint qual,const FXString& type) const {
320   return (FXIcon*)scaleToSize(loadIconFile(filename,type),size,qual);
321   }
322 
323 
324 // Load from data array
loadScaledIconData(const void * pixels,FXint size,FXint qual,const FXString & type) const325 FXIcon *FXIconSource::loadScaledIconData(const void *pixels,FXint size,FXint qual,const FXString& type) const {
326   return (FXIcon*)scaleToSize(loadIconData(pixels,type),size,qual);
327   }
328 
329 
330 // Load icon and scale it such that its dimensions does not exceed given size
loadScaledIconStream(FXStream & store,FXint size,FXint qual,const FXString & type) const331 FXIcon *FXIconSource::loadScaledIconStream(FXStream& store,FXint size,FXint qual,const FXString& type) const {
332   return (FXIcon*)scaleToSize(loadIconStream(store,type),size,qual);
333   }
334 
335 
336 // Load image and scale it such that its dimensions does not exceed given size
loadScaledImageFile(const FXString & filename,FXint size,FXint qual,const FXString & type) const337 FXImage *FXIconSource::loadScaledImageFile(const FXString& filename,FXint size,FXint qual,const FXString& type) const {
338   return scaleToSize(loadImageFile(filename,type),size,qual);
339   }
340 
341 
342 // Load from data array
loadScaledImageData(const void * pixels,FXint size,FXint qual,const FXString & type) const343 FXImage *FXIconSource::loadScaledImageData(const void *pixels,FXint size,FXint qual,const FXString& type) const {
344   return (FXImage*)scaleToSize(loadImageData(pixels,type),size,qual);
345   }
346 
347 
348 // Load image and scale it such that its dimensions does not exceed given size
loadScaledImageStream(FXStream & store,FXint size,FXint qual,const FXString & type) const349 FXImage *FXIconSource::loadScaledImageStream(FXStream& store,FXint size,FXint qual,const FXString& type) const {
350   return scaleToSize(loadImageStream(store,type),size,qual);
351   }
352 
353 
354 // Save to stream
save(FXStream & store) const355 void FXIconSource::save(FXStream& store) const {
356   FXObject::save(store);
357   store << app;
358   }
359 
360 
361 // Load from stream
load(FXStream & store)362 void FXIconSource::load(FXStream& store){
363   FXObject::load(store);
364   store >> app;
365   }
366 
367 
368 // Delete
~FXIconSource()369 FXIconSource::~FXIconSource(){
370   FXTRACE((100,"FXIconSource::~FXIconSource\n"));
371   app=(FXApp*)-1L;
372   }
373 
374 
375 
376 }
377