You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

198 lines
5.0KB

  1. //
  2. // "$Id: Fl_PNM_Image.cxx 7903 2010-11-28 21:06:39Z matt $"
  3. //
  4. // Fl_PNM_Image routines.
  5. //
  6. // Copyright 1997-2010 by Easy Software Products.
  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. // Contents:
  28. //
  29. // Fl_PNM_Image::Fl_PNM_Image() - Load a PNM image...
  30. //
  31. //
  32. // Include necessary header files...
  33. //
  34. #include <FL/Fl.H>
  35. #include <FL/Fl_PNM_Image.H>
  36. #include <stdio.h>
  37. #include <stdlib.h>
  38. #include <FL/fl_utf8.h>
  39. #include "flstring.h"
  40. //
  41. // 'Fl_PNM_Image::Fl_PNM_Image()' - Load a PNM image...
  42. //
  43. /**
  44. The constructor loads the named PNM image.
  45. <P>The inherited destructor free all memory and server resources that are used by the image.
  46. */
  47. Fl_PNM_Image::Fl_PNM_Image(const char *name) // I - File to read
  48. : Fl_RGB_Image(0,0,0) {
  49. FILE *fp; // File pointer
  50. int x, y; // Looping vars
  51. char line[1024], // Input line
  52. *lineptr; // Pointer in line
  53. uchar *ptr, // Pointer to pixel values
  54. byte, // Byte from file
  55. bit; // Bit in pixel
  56. int format, // Format of PNM file
  57. val, // Pixel value
  58. maxval; // Maximum pixel value
  59. if ((fp = fl_fopen(name, "rb")) == NULL) return;
  60. //
  61. // Read the file header in the format:
  62. //
  63. // Pformat
  64. // # comment1
  65. // # comment2
  66. // ...
  67. // # commentN
  68. // width
  69. // height
  70. // max sample
  71. //
  72. lineptr = fgets(line, sizeof(line), fp);
  73. if (!lineptr) {
  74. fclose(fp);
  75. Fl::error("Early end-of-file in PNM file \"%s\"!", name);
  76. return;
  77. }
  78. lineptr ++;
  79. format = atoi(lineptr);
  80. while (isdigit(*lineptr)) lineptr ++;
  81. if (format == 7) lineptr = (char *)"";
  82. while (lineptr != NULL && w() == 0) {
  83. if (*lineptr == '\0' || *lineptr == '#') {
  84. lineptr = fgets(line, sizeof(line), fp);
  85. } else if (isdigit(*lineptr)) {
  86. w(strtol(lineptr, &lineptr, 10));
  87. } else lineptr ++;
  88. }
  89. while (lineptr != NULL && h() == 0) {
  90. if (*lineptr == '\0' || *lineptr == '#') {
  91. lineptr = fgets(line, sizeof(line), fp);
  92. } else if (isdigit(*lineptr)) {
  93. h(strtol(lineptr, &lineptr, 10));
  94. } else lineptr ++;
  95. }
  96. if (format != 1 && format != 4) {
  97. maxval = 0;
  98. while (lineptr != NULL && maxval == 0) {
  99. if (*lineptr == '\0' || *lineptr == '#') {
  100. lineptr = fgets(line, sizeof(line), fp);
  101. } else if (isdigit(*lineptr)) {
  102. maxval = strtol(lineptr, &lineptr, 10);
  103. } else lineptr ++;
  104. }
  105. } else maxval = 1;
  106. // Allocate memory...
  107. if (format == 1 || format == 2 || format == 4 || format == 5) d(1);
  108. else d(3);
  109. // printf("%s = %dx%dx%d\n", name, w(), h(), d());
  110. array = new uchar[w() * h() * d()];
  111. alloc_array = 1;
  112. // Read the image file...
  113. for (y = 0; y < h(); y ++) {
  114. ptr = (uchar *)array + y * w() * d();
  115. switch (format) {
  116. case 1 :
  117. case 2 :
  118. for (x = w(); x > 0; x --)
  119. if (fscanf(fp, "%d", &val) == 1) *ptr++ = (uchar)(255 * val / maxval);
  120. break;
  121. case 3 :
  122. for (x = w(); x > 0; x --) {
  123. if (fscanf(fp, "%d", &val) == 1) *ptr++ = (uchar)(255 * val / maxval);
  124. if (fscanf(fp, "%d", &val) == 1) *ptr++ = (uchar)(255 * val / maxval);
  125. if (fscanf(fp, "%d", &val) == 1) *ptr++ = (uchar)(255 * val / maxval);
  126. }
  127. break;
  128. case 4 :
  129. for (x = w(), byte = (uchar)getc(fp), bit = 128; x > 0; x --) {
  130. if (byte & bit) *ptr++ = 255;
  131. else *ptr++ = 0;
  132. if (bit > 1) bit >>= 1;
  133. else {
  134. bit = 128;
  135. byte = (uchar)getc(fp);
  136. }
  137. }
  138. break;
  139. case 5 :
  140. case 6 :
  141. if (maxval < 256) {
  142. if (fread(ptr, w(), d(), fp)) { /* ignored */ }
  143. } else {
  144. for (x = d() * w(); x > 0; x --) {
  145. val = (uchar)getc(fp);
  146. val = (val<<8)|(uchar)getc(fp);
  147. *ptr++ = (255*val)/maxval;
  148. }
  149. }
  150. break;
  151. case 7 : /* XV 3:3:2 thumbnail format */
  152. for (x = w(); x > 0; x --) {
  153. byte = (uchar)getc(fp);
  154. *ptr++ = (uchar)(255 * ((byte >> 5) & 7) / 7);
  155. *ptr++ = (uchar)(255 * ((byte >> 2) & 7) / 7);
  156. *ptr++ = (uchar)(255 * (byte & 3) / 3);
  157. }
  158. break;
  159. }
  160. }
  161. fclose(fp);
  162. }
  163. //
  164. // End of "$Id: Fl_PNM_Image.cxx 7903 2010-11-28 21:06:39Z matt $".
  165. //