Fluid_Image.cxx 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. //
  2. // "$Id: Fluid_Image.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $"
  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. Distribution and use rights are outlined in
  9. // the file "COPYING" which should have been included with this file. If this
  10. // file is missing or damaged, see the license at:
  11. //
  12. // http://www.fltk.org/COPYING.php
  13. //
  14. // Please report all bugs and problems on the following page:
  15. //
  16. // http://www.fltk.org/str.php
  17. //
  18. #include <FL/Fl.H>
  19. #include <FL/Fl_Widget.H>
  20. #include "Fl_Type.h"
  21. #include "Fluid_Image.h"
  22. #include "../src/flstring.h"
  23. #include <stdio.h>
  24. #include <errno.h>
  25. #include <stdlib.h>
  26. #include <FL/filename.H>
  27. extern void goto_source_dir(); // in fluid.C
  28. extern void leave_source_dir(); // in fluid.C
  29. void Fluid_Image::image(Fl_Widget *o) {
  30. if (o->window() != o) o->image(img);
  31. }
  32. void Fluid_Image::deimage(Fl_Widget *o) {
  33. if (o->window() != o) o->deimage(img);
  34. }
  35. static int pixmap_header_written = 0;
  36. static int bitmap_header_written = 0;
  37. static int image_header_written = 0;
  38. static int jpeg_header_written = 0;
  39. void Fluid_Image::write_static() {
  40. if (!img) return;
  41. if (img->count() > 1) {
  42. // Write Pixmap data...
  43. write_c("\n");
  44. if (pixmap_header_written != write_number) {
  45. write_c("#include <FL/Fl_Pixmap.H>\n");
  46. pixmap_header_written = write_number;
  47. }
  48. write_c("static const char *%s[] = {\n",
  49. unique_id(this, "idata", fl_filename_name(name()), 0));
  50. write_cstring(img->data()[0], strlen(img->data()[0]));
  51. int i;
  52. int ncolors, chars_per_color;
  53. sscanf(img->data()[0], "%*d%*d%d%d", &ncolors, &chars_per_color);
  54. if (ncolors < 0) {
  55. write_c(",\n");
  56. write_cstring(img->data()[1], ncolors * -4);
  57. i = 2;
  58. } else {
  59. for (i = 1; i <= ncolors; i ++) {
  60. write_c(",\n");
  61. write_cstring(img->data()[i], strlen(img->data()[i]));
  62. }
  63. }
  64. for (; i < img->count(); i ++) {
  65. write_c(",\n");
  66. write_cstring(img->data()[i], img->w() * chars_per_color);
  67. }
  68. write_c("\n};\n");
  69. write_c("static Fl_Pixmap %s(%s);\n",
  70. unique_id(this, "image", fl_filename_name(name()), 0),
  71. unique_id(this, "idata", fl_filename_name(name()), 0));
  72. } else if (img->d() == 0) {
  73. // Write Bitmap data...
  74. write_c("\n");
  75. if (bitmap_header_written != write_number) {
  76. write_c("#include <FL/Fl_Bitmap.H>\n");
  77. bitmap_header_written = write_number;
  78. }
  79. write_c("static unsigned char %s[] =\n",
  80. unique_id(this, "idata", fl_filename_name(name()), 0));
  81. write_cdata(img->data()[0], ((img->w() + 7) / 8) * img->h());
  82. write_c(";\n");
  83. write_c("static Fl_Bitmap %s(%s, %d, %d);\n",
  84. unique_id(this, "image", fl_filename_name(name()), 0),
  85. unique_id(this, "idata", fl_filename_name(name()), 0),
  86. img->w(), img->h());
  87. } else if (strcmp(fl_filename_ext(name()), ".jpg")==0) {
  88. // Write jpeg image data...
  89. write_c("\n");
  90. if (jpeg_header_written != write_number) {
  91. write_c("#include <FL/Fl_JPEG_Image.H>\n");
  92. jpeg_header_written = write_number;
  93. }
  94. write_c("static unsigned char %s[] =\n",
  95. unique_id(this, "idata", fl_filename_name(name()), 0));
  96. FILE *f = fl_fopen(name(), "rb");
  97. if (!f) {
  98. // message = "Can't include binary file. Can't open";
  99. } else {
  100. fseek(f, 0, SEEK_END);
  101. size_t nData = ftell(f);
  102. fseek(f, 0, SEEK_SET);
  103. if (nData) {
  104. char *data = (char*)calloc(nData, 1);
  105. if (fread(data, nData, 1, f)==0) { /* ignore */ }
  106. write_cdata(data, nData);
  107. free(data);
  108. }
  109. fclose(f);
  110. }
  111. write_c(";\n");
  112. write_c("static Fl_JPEG_Image %s(\"%s\", %s);\n",
  113. unique_id(this, "image", fl_filename_name(name()), 0),
  114. fl_filename_name(name()),
  115. unique_id(this, "idata", fl_filename_name(name()), 0));
  116. } else {
  117. // Write image data...
  118. write_c("\n");
  119. if (image_header_written != write_number) {
  120. write_c("#include <FL/Fl_Image.H>\n");
  121. image_header_written = write_number;
  122. }
  123. write_c("static unsigned char %s[] =\n",
  124. unique_id(this, "idata", fl_filename_name(name()), 0));
  125. write_cdata(img->data()[0], (img->w() * img->d() + img->ld()) * img->h());
  126. write_c(";\n");
  127. write_c("static Fl_RGB_Image %s(%s, %d, %d, %d, %d);\n",
  128. unique_id(this, "image", fl_filename_name(name()), 0),
  129. unique_id(this, "idata", fl_filename_name(name()), 0),
  130. img->w(), img->h(), img->d(), img->ld());
  131. }
  132. }
  133. void Fluid_Image::write_code(const char *var, int inactive) {
  134. if (!img) return;
  135. write_c("%s%s->%s(%s);\n", indent(), var, inactive ? "deimage" : "image",
  136. unique_id(this, "image", fl_filename_name(name()), 0));
  137. }
  138. ////////////////////////////////////////////////////////////////
  139. static Fluid_Image** images = 0; // sorted list
  140. static int numimages = 0;
  141. static int tablesize = 0;
  142. Fluid_Image* Fluid_Image::find(const char *iname) {
  143. if (!iname || !*iname) return 0;
  144. // first search to see if it exists already:
  145. int a = 0;
  146. int b = numimages;
  147. while (a < b) {
  148. int c = (a+b)/2;
  149. int i = strcmp(iname,images[c]->name_);
  150. if (i < 0) b = c;
  151. else if (i > 0) a = c+1;
  152. else return images[c];
  153. }
  154. // no, so now see if the file exists:
  155. goto_source_dir();
  156. FILE *f = fl_fopen(iname,"rb");
  157. if (!f) {
  158. read_error("%s : %s",iname,strerror(errno));
  159. leave_source_dir();
  160. return 0;
  161. }
  162. fclose(f);
  163. Fluid_Image *ret = new Fluid_Image(iname);
  164. if (!ret->img || !ret->img->w() || !ret->img->h()) {
  165. delete ret;
  166. ret = 0;
  167. read_error("%s : unrecognized image format", iname);
  168. }
  169. leave_source_dir();
  170. if (!ret) return 0;
  171. // make a new entry in the table:
  172. numimages++;
  173. if (numimages > tablesize) {
  174. tablesize = tablesize ? 2*tablesize : 16;
  175. if (images) images = (Fluid_Image**)realloc(images, tablesize*sizeof(Fluid_Image*));
  176. else images = (Fluid_Image**)malloc(tablesize*sizeof(Fluid_Image*));
  177. }
  178. for (b = numimages-1; b > a; b--) images[b] = images[b-1];
  179. images[a] = ret;
  180. return ret;
  181. }
  182. Fluid_Image::Fluid_Image(const char *iname) {
  183. name_ = strdup(iname);
  184. written = 0;
  185. refcount = 0;
  186. img = Fl_Shared_Image::get(iname);
  187. }
  188. void Fluid_Image::increment() {
  189. ++refcount;
  190. }
  191. void Fluid_Image::decrement() {
  192. --refcount;
  193. if (refcount > 0) return;
  194. delete this;
  195. }
  196. Fluid_Image::~Fluid_Image() {
  197. int a;
  198. if (images) {
  199. for (a = 0;; a++) if (images[a] == this) break;
  200. numimages--;
  201. for (; a < numimages; a++) images[a] = images[a+1];
  202. }
  203. if (img) img->release();
  204. free((void*)name_);
  205. }
  206. ////////////////////////////////////////////////////////////////
  207. #include <FL/Fl_File_Chooser.H>
  208. const char *ui_find_image_name;
  209. Fluid_Image *ui_find_image(const char *oldname) {
  210. goto_source_dir();
  211. fl_file_chooser_ok_label("Use Image");
  212. const char *name = fl_file_chooser("Image?","Image Files (*.{bm,bmp,gif,jpg,pbm,pgm,png,ppm,xbm,xpm})",oldname,1);
  213. fl_file_chooser_ok_label(NULL);
  214. ui_find_image_name = name;
  215. Fluid_Image *ret = (name && *name) ? Fluid_Image::find(name) : 0;
  216. leave_source_dir();
  217. return ret;
  218. }
  219. //
  220. // End of "$Id: Fluid_Image.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $".
  221. //