Coverage Report

Created: 2025-10-12 06:12

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/jpegoptim/jpegdest.c
Line
Count
Source
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
27
#include <stdio.h>
28
#include <stdlib.h>
29
#include <string.h>
30
#include <jpeglib.h>
31
#include <jerror.h>
32
33
#include "jpegoptim.h"
34
35
36
37
/* custom jpeg destination manager object */
38
39
typedef struct {
40
  struct jpeg_destination_mgr pub; /* public fields */
41
42
  unsigned char **buf_ptr;
43
  size_t *bufsize_ptr;
44
  size_t incsize;
45
46
  unsigned char *buf;
47
  size_t bufsize;
48
49
} jpeg_memory_destination_mgr;
50
51
typedef jpeg_memory_destination_mgr* jpeg_memory_destination_ptr;
52
53
54
55
56
static void jpeg_memory_init_destination (j_compress_ptr cinfo)
57
0
{
58
0
  jpeg_memory_destination_ptr dest = (jpeg_memory_destination_ptr) cinfo->dest;
59
60
0
  dest->pub.next_output_byte = dest->buf;
61
0
  dest->pub.free_in_buffer = dest->bufsize;
62
0
}
63
64
65
static boolean jpeg_memory_empty_output_buffer (j_compress_ptr cinfo)
66
0
{
67
0
  jpeg_memory_destination_ptr dest = (jpeg_memory_destination_ptr) cinfo->dest;
68
0
  unsigned char *newbuf;
69
70
  /* abort if incsize is 0 (no expansion of buffer allowed) */
71
0
  if (dest->incsize == 0) ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 42);
72
73
  /* otherwise, try expanding buffer... */
74
0
  newbuf = realloc(dest->buf,dest->bufsize + dest->incsize);
75
0
  if (!newbuf) ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 42);
76
77
0
  dest->pub.next_output_byte = newbuf + dest->bufsize;
78
0
  dest->pub.free_in_buffer = dest->incsize;
79
80
0
  *dest->buf_ptr = newbuf;
81
0
  dest->buf = newbuf;
82
0
  dest->bufsize += dest->incsize;
83
0
  dest->incsize *= 2;
84
85
0
  return TRUE;
86
0
}
87
88
89
90
static void jpeg_memory_term_destination (j_compress_ptr cinfo)
91
0
{
92
0
  jpeg_memory_destination_ptr dest = (jpeg_memory_destination_ptr) cinfo->dest;
93
94
0
  *dest->buf_ptr = dest->buf;
95
0
  *dest->bufsize_ptr = dest->bufsize - dest->pub.free_in_buffer;
96
0
}
97
98
99
100
void jpeg_memory_dest (j_compress_ptr cinfo, unsigned char **bufptr, size_t *bufsizeptr, size_t incsize)
101
0
{
102
0
  jpeg_memory_destination_ptr dest;
103
104
0
  if (!cinfo || !bufptr || !bufsizeptr)
105
0
    fatal("invalid call to jpeg_memory_dest()");
106
0
  if (!*bufptr || *bufsizeptr == 0)
107
0
    fatal("invalid buffer passed to jpeg_memory_dest()");
108
109
110
  /* Allocate destination manager object for compress object, if needed. */
111
0
  if (!cinfo->dest) {
112
0
    cinfo->dest = (struct jpeg_destination_mgr *)
113
0
      (*cinfo->mem->alloc_small) ( (j_common_ptr) cinfo,
114
0
            JPOOL_PERMANENT,
115
0
            sizeof(jpeg_memory_destination_mgr) );
116
0
  }
117
118
0
  dest = (jpeg_memory_destination_ptr)cinfo->dest;
119
120
0
  dest->buf_ptr = bufptr;
121
0
  dest->buf = *bufptr;
122
0
  dest->bufsize_ptr = bufsizeptr;
123
0
  dest->bufsize = *bufsizeptr;
124
0
  dest->incsize = incsize;
125
126
0
  dest->pub.init_destination = jpeg_memory_init_destination;
127
0
  dest->pub.empty_output_buffer = jpeg_memory_empty_output_buffer;
128
0
  dest->pub.term_destination = jpeg_memory_term_destination;
129
0
}
130
131
132
/* eof :-) */