Coverage Report

Created: 2022-10-31 07:00

/src/ghostpdl/base/gximage1.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2022 Artifex Software, Inc.
2
   All Rights Reserved.
3
4
   This software is provided AS-IS with no warranty, either express or
5
   implied.
6
7
   This software is distributed under license and may not be copied,
8
   modified or distributed except as expressly authorized under the terms
9
   of the license contained in the file LICENSE in this distribution.
10
11
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  1305 Grant Avenue - Suite 200, Novato,
13
   CA 94945, U.S.A., +1(415)492-9861, for further information.
14
*/
15
16
17
/* ImageType 1 initialization */
18
#include "gx.h"
19
#include "gserrors.h"
20
#include "gxiparam.h"
21
#include "gximage.h"
22
#include "stream.h"
23
#include "memory_.h"
24
25
/* Structure descriptor */
26
public_st_gs_image1();
27
28
/*
29
 * Define the image types for ImageType 1 images.
30
 * Note that opaque images and masks have different types, although
31
 * they have the same ImageType.
32
 */
33
static image_proc_sput(gx_image1_sput);
34
static image_proc_sget(gx_image1_sget);
35
static image_proc_release(gx_image1_release);
36
const gx_image_type_t gs_image_type_1 = {
37
    &st_gs_image1, gx_begin_image1,
38
    gx_image1_sput, gx_image1_sget, gx_image1_release, 1
39
};
40
static image_proc_sput(gx_image1_mask_sput);
41
static image_proc_sget(gx_image1_mask_sget);
42
/*
43
 * Image masks are not actually pixel images, so they don't need to
44
 * worry about releasing the color space.
45
 */
46
const gx_image_type_t gs_image_type_mask1 = {
47
    &st_gs_image1, gx_begin_image1,
48
    gx_image1_mask_sput, gx_image1_mask_sget, gx_image_default_release, 1
49
};
50
51
/* Define the procedures for initializing gs_image_ts to default values. */
52
void
53
gs_image_t_init_adjust(gs_image_t * pim, gs_color_space * color_space,
54
                       bool adjust)
55
265k
{
56
265k
    gs_pixel_image_t_init((gs_pixel_image_t *) pim, color_space);
57
265k
    pim->ImageMask = (color_space == NULL);
58
265k
    pim->adjust = adjust;
59
265k
    pim->type = (pim->ImageMask ? &gs_image_type_mask1 : &gs_image_type_1);
60
265k
    pim->Alpha = gs_image_alpha_none;
61
265k
    pim->image_parent_type = gs_image_type1;
62
265k
}
63
void
64
gs_image_t_init_mask_adjust(gs_image_t * pim, bool write_1s, bool adjust)
65
36.0k
{
66
36.0k
    gs_image_t_init(pim, NULL);
67
36.0k
    if (write_1s)
68
8.82k
        pim->Decode[0] = 1, pim->Decode[1] = 0;
69
27.1k
    else
70
27.1k
        pim->Decode[0] = 0, pim->Decode[1] = 1;
71
36.0k
    pim->adjust = adjust;
72
36.0k
}
73
74
/* Start processing an ImageType 1 image. */
75
int
76
gx_begin_image1(gx_device * dev,
77
                const gs_gstate * pgs, const gs_matrix * pmat,
78
                const gs_image_common_t * pic, const gs_int_rect * prect,
79
                const gx_drawing_color * pdcolor, const gx_clip_path * pcpath,
80
                gs_memory_t * mem, gx_image_enum_common_t ** pinfo)
81
330k
{
82
330k
    gx_image_enum *penum;
83
330k
    const gs_image_t *pim = (const gs_image_t *)pic;
84
330k
    int code = gx_image_enum_alloc(pic, prect, mem, &penum);
85
86
330k
    if (code < 0)
87
109
        return code;
88
330k
    penum->alpha = pim->Alpha;
89
330k
    penum->use_mask_color = false;
90
330k
    penum->image_parent_type = pim->image_parent_type;
91
330k
    penum->masked = pim->ImageMask;
92
330k
    penum->adjust =
93
330k
        (pim->ImageMask && pim->adjust ? float2fixed(0.25) : fixed_0);
94
330k
    code = gx_image_enum_begin(dev, pgs, pmat, pic, pdcolor, pcpath, mem,
95
330k
                               penum);
96
330k
    if (code >= 0)
97
330k
        *pinfo = (gx_image_enum_common_t *)penum;
98
30
    else {
99
        /* penum is freed in by gx_image_enum_begin */
100
30
        *pinfo = NULL;
101
30
    }
102
330k
    return code;
103
330k
}
104
105
/* Serialization */
106
107
/*
108
 * We add the Alpha value to the control word.
109
 */
110
111
static int
112
gx_image1_sput(const gs_image_common_t *pic, stream *s,
113
               const gs_color_space **ppcs)
114
15.5k
{
115
15.5k
    const gs_image_t *const pim = (const gs_image_t *)pic;
116
117
15.5k
    return gx_pixel_image_sput((const gs_pixel_image_t *)pic, s, ppcs,
118
15.5k
                               (int)pim->Alpha);
119
15.5k
}
120
121
static int
122
gx_image1_sget(gs_image_common_t *pic, stream *s,
123
               gs_color_space *pcs)
124
114k
{
125
114k
    gs_image1_t *const pim = (gs_image1_t *)pic;
126
114k
    int code = gx_pixel_image_sget((gs_pixel_image_t *)pim, s, pcs);
127
128
114k
    if (code < 0)
129
0
        return code;
130
114k
    pim->type = &gs_image_type_1;
131
114k
    pim->ImageMask = false;
132
114k
    pim->Alpha = code;
133
114k
    pim->image_parent_type = gs_image_type1;
134
114k
    return 0;
135
114k
}
136
137
/*
138
 * Masks have different parameters, so we use a different encoding:
139
 *  FFFFEEDCBA
140
 *      A = 0 if standard ImageMatrix, 1 if explicit ImageMatrix
141
 *      B = 0 if Decode=[0 1], 1 if Decode=[1 0]
142
 *      C = Interpolate
143
 *      D = adjust
144
 *      EE = Alpha
145
 *      FFFF = BitsPerComponent - 1 (only needed for soft masks)
146
 *  Width, encoded as a variable-length uint
147
 *  Height, encoded like Width
148
 *  ImageMatrix (if A = 1), per gs_matrix_store/fetch
149
 */
150
628
#define MI_ImageMatrix 0x01
151
267
#define MI_Decode 0x02
152
226
#define MI_Interpolate 0x04
153
390
#define MI_adjust 0x08
154
524
#define MI_Alpha_SHIFT 4
155
226
#define MI_Alpha_MASK 0x3
156
524
#define MI_BPC_SHIFT 6
157
226
#define MI_BPC_MASK 0xf
158
#define MI_BITS 10
159
160
static int
161
gx_image1_mask_sput(const gs_image_common_t *pic, stream *s,
162
                    const gs_color_space **ignore_ppcs)
163
298
{
164
298
    const gs_image_t *pim = (const gs_image_t *)pic;
165
298
    uint control =
166
298
        (gx_image_matrix_is_default((const gs_data_image_t *)pim) ? 0 :
167
298
         MI_ImageMatrix) |
168
298
        (pim->Decode[0] != 0 ? MI_Decode : 0) |
169
298
        (pim->Interpolate ? MI_Interpolate : 0) |
170
298
        (pim->adjust ? MI_adjust : 0) |
171
298
        (pim->Alpha << MI_Alpha_SHIFT) |
172
298
        ((pim->BitsPerComponent - 1) << MI_BPC_SHIFT);
173
174
298
    sput_variable_uint(s, control);
175
298
    sput_variable_uint(s, (uint)pim->Width);
176
298
    sput_variable_uint(s, (uint)pim->Height);
177
298
    if (control & MI_ImageMatrix)
178
104
        sput_matrix(s, &pim->ImageMatrix);
179
298
    return 0;
180
298
}
181
182
static int
183
gx_image1_mask_sget(gs_image_common_t *pic, stream *s,
184
                    gs_color_space *ignore_pcs)
185
226
{
186
226
    gs_image1_t *const pim = (gs_image1_t *)pic;
187
226
    int code;
188
226
    uint control;
189
190
226
    if ((code = sget_variable_uint(s, &control)) < 0)
191
0
        return code;
192
226
    gs_image_t_init_mask(pim, (control & MI_Decode) != 0);
193
226
    if ((code = sget_variable_uint(s, (uint *)&pim->Width)) < 0 ||
194
226
        (code = sget_variable_uint(s, (uint *)&pim->Height)) < 0
195
226
        )
196
0
        return code;
197
226
    if (control & MI_ImageMatrix) {
198
94
        if ((code = sget_matrix(s, &pim->ImageMatrix)) < 0)
199
0
            return code;
200
94
    } else
201
132
        gx_image_matrix_set_default((gs_data_image_t *)pim);
202
226
    pim->Interpolate = (control & MI_Interpolate) != 0;
203
226
    pim->adjust = (control & MI_adjust) != 0;
204
226
    pim->Alpha = (control >> MI_Alpha_SHIFT) & MI_Alpha_MASK;
205
226
    pim->BitsPerComponent = ((control >> MI_BPC_SHIFT) & MI_BPC_MASK) + 1;
206
226
    return 0;
207
226
}
208
209
static void
210
gx_image1_release(gs_image_common_t *pic, gs_memory_t *mem)
211
0
{
212
0
    gx_pixel_image_release((gs_pixel_image_t *)pic, mem);
213
0
}
214
215
/* Free the image enumerator. */
216
void
217
gx_image_free_enum(gx_image_enum_common_t **ppenum)
218
353k
{
219
353k
    gx_image_enum_common_t  * penum = *ppenum;
220
353k
    gs_memory_t *mem = penum->memory;
221
222
     /* Bug 688845 comment #38 :
223
        Adobe Illustrator creates a Postscript document,
224
        in which an image data procedure executes 'save',
225
        and the corresponding 'restore' appears after the image end.
226
        It causes this procedure is called at a higher save level than
227
        at which the enumerator was allocated, so that gs_free_object below
228
        works idle. Nevertheless we can't leave pointers in the structure,
229
        because they may point to blocks already released
230
        by the client's subclass method for end_image.
231
        Leaving them uncleaned caused a real crash in the garbager - see bug 688845.
232
        So we clean the entire subclassed enumerator here,
233
        rather this is a generic function for base class.
234
        Note the cleaning is neccessaryfor Postscript only,
235
        because other languaged don't implement save-restore.
236
     */
237
353k
    memset(penum, 0, gs_object_size(mem, penum));
238
353k
    gs_free_object(mem, penum, "gx_image_free_enum");
239
353k
    *ppenum = NULL;
240
353k
}