jpegdest.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. /*
  2. * jpegdest.c
  3. *
  4. * Copyright (C) 2014-2022 Timo Kokkonen
  5. * All Rights Reserved.
  6. *
  7. * custom libjpeg "Destination Manager" for saving into RAM
  8. *
  9. * SPDX-License-Identifier: GPL-3.0-or-later
  10. *
  11. * This file is part of JPEGoptim.
  12. *
  13. * JPEGoptim is free software: you can redistribute it and/or modify
  14. * it under the terms of the GNU General Public License as published by
  15. * the Free Software Foundation, either version 3 of the License, or
  16. * (at your option) any later version.
  17. *
  18. * JPEGoptim is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. * GNU General Public License for more details.
  22. *
  23. * You should have received a copy of the GNU General Public License
  24. * along with JPEGoptim. If not, see <https://www.gnu.org/licenses/>.
  25. */
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include <string.h>
  29. #include <jpeglib.h>
  30. #include <jerror.h>
  31. #include "jpegoptim.h"
  32. /* custom jpeg destination manager object */
  33. typedef struct {
  34. struct jpeg_destination_mgr pub; /* public fields */
  35. unsigned char **buf_ptr;
  36. size_t *bufsize_ptr;
  37. size_t incsize;
  38. unsigned char *buf;
  39. size_t bufsize;
  40. } jpeg_memory_destination_mgr;
  41. typedef jpeg_memory_destination_mgr* jpeg_memory_destination_ptr;
  42. void jpeg_memory_init_destination (j_compress_ptr cinfo)
  43. {
  44. jpeg_memory_destination_ptr dest = (jpeg_memory_destination_ptr) cinfo->dest;
  45. dest->pub.next_output_byte = dest->buf;
  46. dest->pub.free_in_buffer = dest->bufsize;
  47. }
  48. boolean jpeg_memory_empty_output_buffer (j_compress_ptr cinfo)
  49. {
  50. jpeg_memory_destination_ptr dest = (jpeg_memory_destination_ptr) cinfo->dest;
  51. unsigned char *newbuf;
  52. /* abort if incsize is 0 (no expansion of buffer allowed) */
  53. if (dest->incsize == 0) ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 42);
  54. /* otherwise, try expanding buffer... */
  55. newbuf = realloc(dest->buf,dest->bufsize + dest->incsize);
  56. if (!newbuf) ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 42);
  57. dest->pub.next_output_byte = newbuf + dest->bufsize;
  58. dest->pub.free_in_buffer = dest->incsize;
  59. *dest->buf_ptr = newbuf;
  60. dest->buf = newbuf;
  61. dest->bufsize += dest->incsize;
  62. dest->incsize *= 2;
  63. return TRUE;
  64. }
  65. void jpeg_memory_term_destination (j_compress_ptr cinfo)
  66. {
  67. jpeg_memory_destination_ptr dest = (jpeg_memory_destination_ptr) cinfo->dest;
  68. *dest->buf_ptr = dest->buf;
  69. *dest->bufsize_ptr = dest->bufsize - dest->pub.free_in_buffer;
  70. }
  71. void jpeg_memory_dest (j_compress_ptr cinfo, unsigned char **bufptr, size_t *bufsizeptr, size_t incsize)
  72. {
  73. jpeg_memory_destination_ptr dest;
  74. if (!cinfo || !bufptr || !bufsizeptr)
  75. fatal("invalid call to jpeg_memory_dest()");
  76. if (!*bufptr || *bufsizeptr == 0)
  77. fatal("invalid buffer passed to jpeg_memory_dest()");
  78. /* Allocate destination manager object for compress object, if needed. */
  79. if (!cinfo->dest) {
  80. cinfo->dest = (struct jpeg_destination_mgr *)
  81. (*cinfo->mem->alloc_small) ( (j_common_ptr) cinfo,
  82. JPOOL_PERMANENT,
  83. sizeof(jpeg_memory_destination_mgr) );
  84. }
  85. dest = (jpeg_memory_destination_ptr)cinfo->dest;
  86. dest->buf_ptr = bufptr;
  87. dest->buf = *bufptr;
  88. dest->bufsize_ptr = bufsizeptr;
  89. dest->bufsize = *bufsizeptr;
  90. dest->incsize = incsize;
  91. dest->pub.init_destination = jpeg_memory_init_destination;
  92. dest->pub.empty_output_buffer = jpeg_memory_empty_output_buffer;
  93. dest->pub.term_destination = jpeg_memory_term_destination;
  94. }
  95. /* eof :-) */