deanimate.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475
  1. /*********************************************************************
  2. *
  3. * File : $Source: /cvsroot/ijbswa/current/deanimate.c,v $
  4. *
  5. * Purpose : Declares functions to manipulate binary images on the
  6. * fly. High-level functions include:
  7. * - Deanimation of GIF images
  8. *
  9. * Copyright : Written by and Copyright (C) 2001 - 2004, 2006 by the
  10. * Privoxy team. https://www.privoxy.org/
  11. *
  12. * Based on the GIF file format specification (see
  13. * http://tronche.com/computer-graphics/gif/gif89a.html)
  14. * and ideas from the Image::DeAnim Perl module by
  15. * Ken MacFarlane, <ksm+cpan@universal.dca.net>
  16. *
  17. * This program is free software; you can redistribute it
  18. * and/or modify it under the terms of the GNU General
  19. * Public License as published by the Free Software
  20. * Foundation; either version 2 of the License, or (at
  21. * your option) any later version.
  22. *
  23. * This program is distributed in the hope that it will
  24. * be useful, but WITHOUT ANY WARRANTY; without even the
  25. * implied warranty of MERCHANTABILITY or FITNESS FOR A
  26. * PARTICULAR PURPOSE. See the GNU General Public
  27. * License for more details.
  28. *
  29. * The GNU General Public License should be included with
  30. * this file. If not, you can view it at
  31. * http://www.gnu.org/copyleft/gpl.html
  32. * or write to the Free Software Foundation, Inc., 59
  33. * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  34. *
  35. **********************************************************************/
  36. #include "config.h"
  37. #include <string.h>
  38. #include <fcntl.h>
  39. #include "project.h"
  40. #include "errlog.h"
  41. #include "deanimate.h"
  42. #include "miscutil.h"
  43. /*********************************************************************
  44. *
  45. * Function : buf_free
  46. *
  47. * Description : Safely frees a struct binbuffer
  48. *
  49. * Parameters :
  50. * 1 : buf = Pointer to the binbuffer to be freed
  51. *
  52. * Returns : N/A
  53. *
  54. *********************************************************************/
  55. void buf_free(struct binbuffer *buf)
  56. {
  57. if (buf == NULL) return;
  58. if (buf->buffer != NULL)
  59. {
  60. free(buf->buffer);
  61. }
  62. free(buf);
  63. }
  64. /*********************************************************************
  65. *
  66. * Function : buf_extend
  67. *
  68. * Description : Ensure that a given binbuffer can hold a given amount
  69. * of bytes, by reallocating its buffer if necessary.
  70. * Allocate new mem in chunks of 1024 bytes, so we don't
  71. * have to realloc() too often.
  72. *
  73. * Parameters :
  74. * 1 : buf = Pointer to the binbuffer
  75. * 2 : length = Desired minimum size
  76. *
  77. *
  78. * Returns : 0 on success, 1 on failure.
  79. *
  80. *********************************************************************/
  81. static int buf_extend(struct binbuffer *buf, size_t length)
  82. {
  83. char *newbuf;
  84. if (buf->offset + length > buf->size)
  85. {
  86. buf->size = ((buf->size + length + (size_t)1023) & ~(size_t)1023);
  87. newbuf = (char *)realloc(buf->buffer, buf->size);
  88. if (newbuf == NULL)
  89. {
  90. freez(buf->buffer);
  91. return 1;
  92. }
  93. else
  94. {
  95. buf->buffer = newbuf;
  96. return 0;
  97. }
  98. }
  99. return 0;
  100. }
  101. /*********************************************************************
  102. *
  103. * Function : buf_copy
  104. *
  105. * Description : Safely copies a given amount of bytes from one
  106. * struct binbuffer to another, advancing the
  107. * offsets appropriately.
  108. *
  109. * Parameters :
  110. * 1 : src = Pointer to the source binbuffer
  111. * 2 : dst = Pointer to the destination binbuffer
  112. * 3 : length = Number of bytes to be copied
  113. *
  114. * Returns : 0 on success, 1 on failure.
  115. *
  116. *********************************************************************/
  117. static int buf_copy(struct binbuffer *src, struct binbuffer *dst, size_t length)
  118. {
  119. /*
  120. * Sanity check: Can't copy more data than we have
  121. */
  122. if (src->offset + length > src->size)
  123. {
  124. return 1;
  125. }
  126. /*
  127. * Ensure that dst can hold the new data
  128. */
  129. if (buf_extend(dst, length))
  130. {
  131. return 1;
  132. }
  133. /*
  134. * Now that it's safe, memcpy() the desired amount of
  135. * data from src to dst and adjust the offsets
  136. */
  137. memcpy(dst->buffer + dst->offset, src->buffer + src->offset, length);
  138. src->offset += length;
  139. dst->offset += length;
  140. return 0;
  141. }
  142. /*********************************************************************
  143. *
  144. * Function : buf_getbyte
  145. *
  146. * Description : Safely gets a byte from a given binbuffer at a
  147. * given offset
  148. *
  149. * Parameters :
  150. * 1 : src = Pointer to the source binbuffer
  151. * 2 : offset = Offset to the desired byte
  152. *
  153. * Returns : The byte on success, or 0 on failure
  154. *
  155. *********************************************************************/
  156. static unsigned char buf_getbyte(const struct binbuffer *src, size_t offset)
  157. {
  158. if (src->offset + offset < src->size)
  159. {
  160. return (unsigned char)*(src->buffer + src->offset + offset);
  161. }
  162. else
  163. {
  164. return '\0';
  165. }
  166. }
  167. /*********************************************************************
  168. *
  169. * Function : gif_skip_data_block
  170. *
  171. * Description : Safely advances the offset of a given struct binbuffer
  172. * that contains a GIF image and whose offset is
  173. * positioned at the start of a data block, behind
  174. * that block.
  175. *
  176. * Parameters :
  177. * 1 : buf = Pointer to the binbuffer
  178. *
  179. * Returns : 0 on success, or 1 on failure
  180. *
  181. *********************************************************************/
  182. static int gif_skip_data_block(struct binbuffer *buf)
  183. {
  184. unsigned char c;
  185. /*
  186. * Data blocks are sequences of chunks, which are headed
  187. * by a one-byte length field, with the last chunk having
  188. * zero length.
  189. */
  190. while((c = buf_getbyte(buf, 0)) != '\0')
  191. {
  192. buf->offset += (size_t)c + 1;
  193. if (buf->offset >= buf->size - 1)
  194. {
  195. return 1;
  196. }
  197. }
  198. buf->offset++;
  199. return 0;
  200. }
  201. /*********************************************************************
  202. *
  203. * Function : gif_extract_image
  204. *
  205. * Description : Safely extracts an image data block from a given
  206. * struct binbuffer that contains a GIF image and whose
  207. * offset is positioned at the start of a data block
  208. * into a given destination binbuffer.
  209. *
  210. * Parameters :
  211. * 1 : src = Pointer to the source binbuffer
  212. * 2 : dst = Pointer to the destination binbuffer
  213. *
  214. * Returns : 0 on success, or 1 on failure
  215. *
  216. *********************************************************************/
  217. static int gif_extract_image(struct binbuffer *src, struct binbuffer *dst)
  218. {
  219. unsigned char c;
  220. /*
  221. * Remember the colormap flag and copy the image head
  222. */
  223. c = buf_getbyte(src, 9);
  224. if (buf_copy(src, dst, 10))
  225. {
  226. return 1;
  227. }
  228. /*
  229. * If the image has a local colormap, copy it.
  230. */
  231. if (c & 0x80)
  232. {
  233. int map_length = 3 * (1 << ((c & 0x07) + 1));
  234. if (map_length <= 0)
  235. {
  236. log_error(LOG_LEVEL_DEANIMATE,
  237. "colormap length = %d (%c)?", map_length, c);
  238. return 1;
  239. }
  240. if (buf_copy(src, dst, (size_t)map_length))
  241. {
  242. return 1;
  243. }
  244. }
  245. if (buf_copy(src, dst, 1)) return 1;
  246. /*
  247. * Copy the image chunk by chunk.
  248. */
  249. while((c = buf_getbyte(src, 0)) != '\0')
  250. {
  251. if (buf_copy(src, dst, 1 + (size_t) c)) return 1;
  252. }
  253. if (buf_copy(src, dst, 1)) return 1;
  254. /*
  255. * Trim and rewind the dst buffer
  256. */
  257. if (NULL == (dst->buffer = (char *)realloc(dst->buffer, dst->offset))) return 1;
  258. dst->size = dst->offset;
  259. dst->offset = 0;
  260. return(0);
  261. }
  262. /*********************************************************************
  263. *
  264. * Function : gif_deanimate
  265. *
  266. * Description : Deanimate a given GIF image, i.e. given a GIF with
  267. * an (optional) image block and an arbitrary number
  268. * of image extension blocks, produce an output GIF with
  269. * only one image block that contains the last image
  270. * (extension) block of the original.
  271. * Also strip Comments, Application extensions, etc.
  272. *
  273. * Parameters :
  274. * 1 : src = Pointer to the source binbuffer
  275. * 2 : dst = Pointer to the destination binbuffer
  276. * 3 : get_first_image = Flag: If set, get the first image
  277. * If unset (default), get the last
  278. *
  279. * Returns : 0 on success, or 1 on failure
  280. *
  281. *********************************************************************/
  282. int gif_deanimate(struct binbuffer *src, struct binbuffer *dst, int get_first_image)
  283. {
  284. unsigned char c;
  285. struct binbuffer *image;
  286. if (NULL == src || NULL == dst)
  287. {
  288. return 1;
  289. }
  290. c = buf_getbyte(src, 10);
  291. /*
  292. * Check & copy GIF header
  293. */
  294. if (strncmp(src->buffer, "GIF89a", 6) && strncmp(src->buffer, "GIF87a", 6))
  295. {
  296. return 1;
  297. }
  298. else
  299. {
  300. if (buf_copy(src, dst, 13))
  301. {
  302. return 1;
  303. }
  304. }
  305. /*
  306. * Look for global colormap and copy if found.
  307. */
  308. if (c & 0x80)
  309. {
  310. int map_length = 3 * (1 << ((c & 0x07) + 1));
  311. if (map_length <= 0)
  312. {
  313. log_error(LOG_LEVEL_DEANIMATE,
  314. "colormap length = %d (%c)?", map_length, c);
  315. return 1;
  316. }
  317. if (buf_copy(src, dst, (size_t)map_length))
  318. {
  319. return 1;
  320. }
  321. }
  322. /*
  323. * Reserve a buffer for the current image block
  324. */
  325. image = zalloc_or_die(sizeof(*image));
  326. /*
  327. * Parse the GIF block by block and copy the relevant
  328. * parts to dst
  329. */
  330. while(src->offset < src->size)
  331. {
  332. switch(buf_getbyte(src, 0))
  333. {
  334. /*
  335. * End-of-GIF Marker: Append current image and return
  336. */
  337. case 0x3b:
  338. goto write;
  339. /*
  340. * Image block: Extract to current image buffer.
  341. */
  342. case 0x2c:
  343. image->offset = 0;
  344. if (gif_extract_image(src, image)) goto failed;
  345. if (get_first_image) goto write;
  346. continue;
  347. /*
  348. * Extension block: Look at next byte and decide
  349. */
  350. case 0x21:
  351. switch (buf_getbyte(src, 1))
  352. {
  353. /*
  354. * Image extension: Copy extension header and image
  355. * to the current image buffer
  356. */
  357. case 0xf9:
  358. image->offset = 0;
  359. if (buf_copy(src, image, 8) || buf_getbyte(src, 0) != 0x2c) goto failed;
  360. if (gif_extract_image(src, image)) goto failed;
  361. if (get_first_image) goto write;
  362. continue;
  363. /*
  364. * Application extension: Skip
  365. */
  366. case 0xff:
  367. if ((src->offset += 14) >= src->size || gif_skip_data_block(src)) goto failed;
  368. continue;
  369. /*
  370. * Comment extension: Skip
  371. */
  372. case 0xfe:
  373. if ((src->offset += 2) >= src->size || gif_skip_data_block(src)) goto failed;
  374. continue;
  375. /*
  376. * Plain text extension: Skip
  377. */
  378. case 0x01:
  379. if ((src->offset += 15) >= src->size || gif_skip_data_block(src)) goto failed;
  380. continue;
  381. /*
  382. * Ooops, what type of extension is that?
  383. */
  384. default:
  385. goto failed;
  386. }
  387. /*
  388. * Ooops, what type of block is that?
  389. */
  390. default:
  391. goto failed;
  392. }
  393. } /* -END- while src */
  394. /*
  395. * Either we got here by goto, or because the GIF is
  396. * bogus and EOF was reached before an end-of-gif marker
  397. * was found.
  398. */
  399. failed:
  400. buf_free(image);
  401. return 1;
  402. /*
  403. * Append the current image to dst and return
  404. */
  405. write:
  406. if (buf_copy(image, dst, image->size)) goto failed;
  407. if (buf_extend(dst, 1)) goto failed;
  408. *(dst->buffer + dst->offset++) = 0x3b;
  409. buf_free(image);
  410. return 0;
  411. }
  412. /*
  413. Local Variables:
  414. tab-width: 3
  415. end:
  416. */