gd_gd.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. #include <stdio.h>
  2. #include <math.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5. #include "gd.h"
  6. #define TRUE 1
  7. #define FALSE 0
  8. /* Exported functions: */
  9. extern void gdImageGd (gdImagePtr im, FILE * out);
  10. /* Use this for commenting out debug-print statements. */
  11. /* Just use the first '#define' to allow all the prints... */
  12. /*#define GD2_DBG(s) (s) */
  13. #define GD2_DBG(s)
  14. /* */
  15. /* Shared code to read color tables from gd file. */
  16. /* */
  17. int _gdGetColors (gdIOCtx * in, gdImagePtr im, int gd2xFlag)
  18. {
  19. int i;
  20. if (gd2xFlag) {
  21. int trueColorFlag;
  22. if (!gdGetByte(&trueColorFlag, in)) {
  23. goto fail1;
  24. }
  25. /* 2.0.12: detect bad truecolor .gd files created by pre-2.0.12.
  26. * Beginning in 2.0.12 truecolor is indicated by the initial 2-byte
  27. * signature.
  28. */
  29. if (trueColorFlag != im->trueColor) {
  30. goto fail1;
  31. }
  32. /* This should have been a word all along */
  33. if (!im->trueColor) {
  34. if (!gdGetWord(&im->colorsTotal, in)) {
  35. goto fail1;
  36. }
  37. if (im->colorsTotal > gdMaxColors) {
  38. goto fail1;
  39. }
  40. }
  41. /* Int to accommodate truecolor single-color transparency */
  42. if (!gdGetInt(&im->transparent, in)) {
  43. goto fail1;
  44. }
  45. } else {
  46. if (!gdGetByte(&im->colorsTotal, in)) {
  47. goto fail1;
  48. }
  49. if (!gdGetWord(&im->transparent, in)) {
  50. goto fail1;
  51. }
  52. if (im->transparent == 257) {
  53. im->transparent = (-1);
  54. }
  55. }
  56. GD2_DBG(printf("Palette had %d colours (T=%d)\n", im->colorsTotal, im->transparent));
  57. if (im->trueColor) {
  58. return TRUE;
  59. }
  60. for (i = 0; i < gdMaxColors; i++) {
  61. if (!gdGetByte(&im->red[i], in)) {
  62. goto fail1;
  63. }
  64. if (!gdGetByte(&im->green[i], in)) {
  65. goto fail1;
  66. }
  67. if (!gdGetByte(&im->blue[i], in)) {
  68. goto fail1;
  69. }
  70. if (gd2xFlag) {
  71. if (!gdGetByte(&im->alpha[i], in)) {
  72. goto fail1;
  73. }
  74. }
  75. }
  76. for (i = 0; i < im->colorsTotal; i++) {
  77. im->open[i] = 0;
  78. }
  79. return TRUE;
  80. fail1:
  81. return FALSE;
  82. }
  83. /* */
  84. /* Use the common basic header info to make the image object. */
  85. /* */
  86. static gdImagePtr _gdCreateFromFile (gdIOCtx * in, int *sx, int *sy)
  87. {
  88. gdImagePtr im;
  89. int gd2xFlag = 0;
  90. int trueColorFlag = 0;
  91. if (!gdGetWord(sx, in)) {
  92. goto fail1;
  93. }
  94. if (*sx == 65535 || *sx == 65534) {
  95. /* This is a gd 2.0 .gd file */
  96. gd2xFlag = 1;
  97. /* 2.0.12: 65534 signals a truecolor .gd file. There is a slight redundancy here but we can live with it. */
  98. if (*sx == 65534) {
  99. trueColorFlag = 1;
  100. }
  101. if (!gdGetWord(sx, in)) {
  102. goto fail1;
  103. }
  104. }
  105. if (!gdGetWord(sy, in)) {
  106. goto fail1;
  107. }
  108. GD2_DBG(printf("Image is %dx%d\n", *sx, *sy));
  109. if (trueColorFlag) {
  110. im = gdImageCreateTrueColor(*sx, *sy);
  111. } else {
  112. im = gdImageCreate(*sx, *sy);
  113. }
  114. if(!im) {
  115. goto fail1;
  116. }
  117. if (!_gdGetColors(in, im, gd2xFlag)) {
  118. goto fail2;
  119. }
  120. return im;
  121. fail2:
  122. gdImageDestroy(im);
  123. fail1:
  124. return 0;
  125. }
  126. gdImagePtr gdImageCreateFromGd (FILE * inFile)
  127. {
  128. gdImagePtr im;
  129. gdIOCtx *in;
  130. in = gdNewFileCtx(inFile);
  131. im = gdImageCreateFromGdCtx(in);
  132. in->gd_free(in);
  133. return im;
  134. }
  135. gdImagePtr gdImageCreateFromGdPtr (int size, void *data)
  136. {
  137. gdImagePtr im;
  138. gdIOCtx *in = gdNewDynamicCtxEx(size, data, 0);
  139. im = gdImageCreateFromGdCtx(in);
  140. in->gd_free(in);
  141. return im;
  142. }
  143. gdImagePtr gdImageCreateFromGdCtx (gdIOCtxPtr in)
  144. {
  145. int sx, sy;
  146. int x, y;
  147. gdImagePtr im;
  148. /* Read the header */
  149. im = _gdCreateFromFile(in, &sx, &sy);
  150. if (im == NULL) {
  151. goto fail1;
  152. }
  153. /* Then the data... */
  154. /* 2.0.12: support truecolor properly in .gd as well as in .gd2. Problem reported by Andreas Pfaller. */
  155. if (im->trueColor) {
  156. for (y = 0; y < sy; y++) {
  157. for (x = 0; x < sx; x++) {
  158. int pix;
  159. if (!gdGetInt(&pix, in)) {
  160. goto fail2;
  161. }
  162. im->tpixels[y][x] = pix;
  163. }
  164. }
  165. } else {
  166. for (y = 0; y < sy; y++) {
  167. for (x = 0; x < sx; x++) {
  168. int ch;
  169. ch = gdGetC(in);
  170. if (ch == EOF) {
  171. goto fail2;
  172. }
  173. /* ROW-MAJOR IN GD 1.3 */
  174. im->pixels[y][x] = ch;
  175. }
  176. }
  177. }
  178. return im;
  179. fail2:
  180. gdImageDestroy (im);
  181. fail1:
  182. return 0;
  183. }
  184. void _gdPutColors (gdImagePtr im, gdIOCtx * out)
  185. {
  186. int i;
  187. gdPutC(im->trueColor, out);
  188. if (!im->trueColor) {
  189. gdPutWord(im->colorsTotal, out);
  190. }
  191. gdPutInt(im->transparent, out);
  192. if (!im->trueColor) {
  193. for (i = 0; i < gdMaxColors; i++) {
  194. gdPutC((unsigned char) im->red[i], out);
  195. gdPutC((unsigned char) im->green[i], out);
  196. gdPutC((unsigned char) im->blue[i], out);
  197. gdPutC((unsigned char) im->alpha[i], out);
  198. }
  199. }
  200. }
  201. static void _gdPutHeader (gdImagePtr im, gdIOCtx * out)
  202. {
  203. /* 65535 indicates this is a gd 2.x .gd file.
  204. * 2.0.12: 65534 indicates truecolor.
  205. */
  206. if (im->trueColor) {
  207. gdPutWord(65534, out);
  208. } else {
  209. gdPutWord(65535, out);
  210. }
  211. gdPutWord(im->sx, out);
  212. gdPutWord(im->sy, out);
  213. _gdPutColors(im, out);
  214. }
  215. static void _gdImageGd (gdImagePtr im, gdIOCtx * out)
  216. {
  217. int x, y;
  218. _gdPutHeader(im, out);
  219. for (y = 0; y < im->sy; y++) {
  220. for (x = 0; x < im->sx; x++) {
  221. /* ROW-MAJOR IN GD 1.3 */
  222. if (im->trueColor) {
  223. gdPutInt(im->tpixels[y][x], out);
  224. } else {
  225. gdPutC((unsigned char) im->pixels[y][x], out);
  226. }
  227. }
  228. }
  229. }
  230. void gdImageGd (gdImagePtr im, FILE * outFile)
  231. {
  232. gdIOCtx *out = gdNewFileCtx(outFile);
  233. _gdImageGd(im, out);
  234. out->gd_free(out);
  235. }
  236. void *gdImageGdPtr (gdImagePtr im, int *size)
  237. {
  238. void *rv;
  239. gdIOCtx *out = gdNewDynamicCtx(2048, NULL);
  240. _gdImageGd(im, out);
  241. rv = gdDPExtractData(out, size);
  242. out->gd_free(out);
  243. return rv;
  244. }