Coverage Report

Created: 2026-03-31 06:56

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/imagemagick/coders/cip.c
Line
Count
Source
1
/*
2
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3
%                                                                             %
4
%                                                                             %
5
%                             CCCC  IIIII  PPPP                               %
6
%                            C        I    P   P                              %
7
%                            C        I    PPPP                               %
8
%                            C        I    P                                  %
9
%                             CCCC  IIIII  P                                  %
10
%                                                                             %
11
%                                                                             %
12
%                  Read/Write Cisco IP Phone Image Format                     %
13
%                                                                             %
14
%                              Software Design                                %
15
%                                   Cristy                                    %
16
%                                April 2004                                   %
17
%                                                                             %
18
%                                                                             %
19
%  Copyright @ 1999 ImageMagick Studio LLC, a non-profit organization         %
20
%  dedicated to making software imaging solutions freely available.           %
21
%                                                                             %
22
%  You may not use this file except in compliance with the License.  You may  %
23
%  obtain a copy of the License at                                            %
24
%                                                                             %
25
%    https://imagemagick.org/license/                                         %
26
%                                                                             %
27
%  Unless required by applicable law or agreed to in writing, software        %
28
%  distributed under the License is distributed on an "AS IS" BASIS,          %
29
%  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
30
%  See the License for the specific language governing permissions and        %
31
%  limitations under the License.                                             %
32
%                                                                             %
33
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
34
%
35
%
36
*/
37

38
/*
39
  Include declarations.
40
*/
41
#include "MagickCore/studio.h"
42
#include "MagickCore/blob.h"
43
#include "MagickCore/blob-private.h"
44
#include "MagickCore/cache.h"
45
#include "MagickCore/color-private.h"
46
#include "MagickCore/colorspace.h"
47
#include "MagickCore/colorspace-private.h"
48
#include "MagickCore/constitute.h"
49
#include "MagickCore/exception.h"
50
#include "MagickCore/exception-private.h"
51
#include "MagickCore/image.h"
52
#include "MagickCore/image-private.h"
53
#include "MagickCore/list.h"
54
#include "MagickCore/magick.h"
55
#include "MagickCore/memory_.h"
56
#include "MagickCore/monitor.h"
57
#include "MagickCore/monitor-private.h"
58
#include "MagickCore/pixel-accessor.h"
59
#include "MagickCore/property.h"
60
#include "MagickCore/quantize.h"
61
#include "MagickCore/quantum-private.h"
62
#include "MagickCore/static.h"
63
#include "MagickCore/string_.h"
64
#include "MagickCore/module.h"
65
#include "MagickCore/utility.h"
66

67
/*
68
  Forward declarations.
69
*/
70
static MagickBooleanType
71
  WriteCIPImage(const ImageInfo *,Image *,ExceptionInfo *);
72

73
/*
74
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
75
%                                                                             %
76
%                                                                             %
77
%                                                                             %
78
%   R e g i s t e r C I P I m a g e                                           %
79
%                                                                             %
80
%                                                                             %
81
%                                                                             %
82
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
83
%
84
%  RegisterCIPImage() adds properties for the CIP IP phone image format to
85
%  the list of supported formats.  The properties include the image format
86
%  tag, a method to read and/or write the format, whether the format
87
%  supports the saving of more than one frame to the same file or blob,
88
%  whether the format supports native in-memory I/O, and a brief
89
%  description of the format.
90
%
91
%  The format of the RegisterCIPImage method is:
92
%
93
%      size_t RegisterCIPImage(void)
94
%
95
*/
96
ModuleExport size_t RegisterCIPImage(void)
97
8
{
98
8
  MagickInfo
99
8
    *entry;
100
101
8
  entry=AcquireMagickInfo("CIP","CIP","Cisco IP phone image format");
102
8
  entry->encoder=(EncodeImageHandler *) WriteCIPImage;
103
8
  entry->flags^=CoderAdjoinFlag;
104
8
  (void) RegisterMagickInfo(entry);
105
8
  return(MagickImageCoderSignature);
106
8
}
107

108
/*
109
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
110
%                                                                             %
111
%                                                                             %
112
%                                                                             %
113
%   U n r e g i s t e r C I P I m a g e                                       %
114
%                                                                             %
115
%                                                                             %
116
%                                                                             %
117
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
118
%
119
%  UnregisterCIPImage() removes format registrations made by the
120
%  CIP module from the list of supported formats.
121
%
122
%  The format of the UnregisterCIPImage method is:
123
%
124
%      UnregisterCIPImage(void)
125
%
126
*/
127
ModuleExport void UnregisterCIPImage(void)
128
0
{
129
0
  (void) UnregisterMagickInfo("CIP");
130
0
}
131

132
/*
133
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
134
%                                                                             %
135
%                                                                             %
136
%                                                                             %
137
%   W r i t e C I P I m a g e                                                 %
138
%                                                                             %
139
%                                                                             %
140
%                                                                             %
141
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
142
%
143
%  Procedure WriteCIPImage() writes an image to a file in the Cisco IP phone
144
%  image format.
145
%
146
%  The format of the WriteCIPImage method is:
147
%
148
%      MagickBooleanType WriteCIPImage(const ImageInfo *image_info,
149
%        Image *image,ExceptionInfo *exception)
150
%
151
%  A description of each parameter follows.
152
%
153
%    o image_info: the image info.
154
%
155
%    o image:  The image.
156
%
157
%    o exception: return any errors or warnings in this structure.
158
%
159
*/
160
static MagickBooleanType WriteCIPImage(const ImageInfo *image_info,Image *image,
161
  ExceptionInfo *exception)
162
0
{
163
0
  char
164
0
    buffer[MagickPathExtent];
165
166
0
  const char
167
0
    *value;
168
169
0
  MagickBooleanType
170
0
    status;
171
172
0
  const Quantum
173
0
    *p;
174
175
0
  ssize_t
176
0
    i,
177
0
    x;
178
179
0
  ssize_t
180
0
    y;
181
182
0
  unsigned char
183
0
    byte;
184
185
  /*
186
    Open output image file.
187
  */
188
0
  assert(image_info != (const ImageInfo *) NULL);
189
0
  assert(image_info->signature == MagickCoreSignature);
190
0
  assert(image != (Image *) NULL);
191
0
  assert(image->signature == MagickCoreSignature);
192
0
  assert(exception != (ExceptionInfo *) NULL);
193
0
  assert(exception->signature == MagickCoreSignature);
194
0
  if (IsEventLogging() != MagickFalse)
195
0
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
196
0
  status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
197
0
  if (status == MagickFalse)
198
0
    return(status);
199
0
  (void) WriteBlobString(image,"<CiscoIPPhoneImage>\n");
200
0
  value=GetImageProperty(image,"label",exception);
201
0
  if (value != (const char *) NULL)
202
0
    (void) FormatLocaleString(buffer,MagickPathExtent,"<Title>%s</Title>\n",
203
0
      value);
204
0
  else
205
0
    {
206
0
      char
207
0
        basename[MagickPathExtent];
208
209
0
      GetPathComponent(image->filename,BasePath,basename);
210
0
      (void) FormatLocaleString(buffer,MagickPathExtent,"<Title>%s</Title>\n",
211
0
        basename);
212
0
    }
213
0
  (void) WriteBlobString(image,buffer);
214
0
  (void) FormatLocaleString(buffer,MagickPathExtent,
215
0
    "<LocationX>%.20g</LocationX>\n",(double) image->page.x);
216
0
  (void) WriteBlobString(image,buffer);
217
0
  (void) FormatLocaleString(buffer,MagickPathExtent,
218
0
    "<LocationY>%.20g</LocationY>\n",(double) image->page.y);
219
0
  (void) WriteBlobString(image,buffer);
220
0
  (void) FormatLocaleString(buffer,MagickPathExtent,"<Width>%.20g</Width>\n",
221
0
    (double) (image->columns+(image->columns % 2)));
222
0
  (void) WriteBlobString(image,buffer);
223
0
  (void) FormatLocaleString(buffer,MagickPathExtent,"<Height>%.20g</Height>\n",
224
0
    (double) image->rows);
225
0
  (void) WriteBlobString(image,buffer);
226
0
  (void) FormatLocaleString(buffer,MagickPathExtent,"<Depth>2</Depth>\n");
227
0
  (void) WriteBlobString(image,buffer);
228
0
  (void) WriteBlobString(image,"<Data>");
229
0
  if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
230
0
    (void) TransformImageColorspace(image,sRGBColorspace,exception);
231
0
  for (y=0; y < (ssize_t) image->rows; y++)
232
0
  {
233
0
    p=GetVirtualPixels(image,0,y,image->columns,1,exception);
234
0
    if (p == (const Quantum *) NULL)
235
0
      break;
236
0
    for (x=0; x < ((ssize_t) image->columns-3); x+=4)
237
0
    {
238
0
      byte=(unsigned char)
239
0
        ((((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+3*GetPixelChannels(image)))/QuantumRange) & 0x03) << 6) |
240
0
         (((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+2*GetPixelChannels(image)))/QuantumRange) & 0x03) << 4) |
241
0
         (((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+1*GetPixelChannels(image)))/QuantumRange) & 0x03) << 2) |
242
0
         (((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+0*GetPixelChannels(image)))/QuantumRange) & 0x03) << 0));
243
0
      (void) FormatLocaleString(buffer,MagickPathExtent,"%02x",byte);
244
0
      (void) WriteBlobString(image,buffer);
245
0
      p+=(ptrdiff_t) GetPixelChannels(image);
246
0
    }
247
0
    if ((image->columns % 4) != 0)
248
0
      {
249
0
        byte=0;
250
0
        for ( ; x < (ssize_t) image->columns; x++)
251
0
        {
252
0
          i=x % 4;
253
0
          switch (i)
254
0
          {
255
0
            case 0:
256
0
            {
257
0
              byte|=(unsigned char) (((size_t) (3*ClampToQuantum(GetPixelLuma(
258
0
                image,p+MagickMin(i,3)*(ssize_t) GetPixelChannels(image)))/
259
0
                QuantumRange) & 0x03) << 6);
260
0
              break;
261
0
            }
262
0
            case 1:
263
0
            {
264
0
              byte|=(unsigned char) (((size_t) (3*ClampToQuantum(GetPixelLuma(
265
0
                image,p+MagickMin(i,2)*(ssize_t) GetPixelChannels(image)))/
266
0
                QuantumRange) & 0x03) << 4);
267
0
              break;
268
0
            }
269
0
            case 2:
270
0
            {
271
0
              byte|=(unsigned char) (((size_t) (3*ClampToQuantum(GetPixelLuma(
272
0
                image,p+MagickMin(i,1)*(ssize_t) GetPixelChannels(image)))/
273
0
                QuantumRange) & 0x03) << 2);
274
0
              break;
275
0
            }
276
0
            case 3:
277
0
            {
278
0
              byte|=(unsigned char) (((size_t) (3*ClampToQuantum(GetPixelLuma(
279
0
                image,p+MagickMin(i,0)*(ssize_t) GetPixelChannels(image)))/
280
0
                QuantumRange) & 0x03) << 0);
281
0
              break;
282
0
            }
283
0
          }
284
0
        }
285
0
        (void) FormatLocaleString(buffer,MagickPathExtent,"%02x",~byte);
286
0
        (void) WriteBlobString(image,buffer);
287
0
      }
288
0
    status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
289
0
      image->rows);
290
0
    if (status == MagickFalse)
291
0
      break;
292
0
  }
293
0
  (void) WriteBlobString(image,"</Data>\n");
294
0
  (void) WriteBlobString(image,"</CiscoIPPhoneImage>\n");
295
0
  if (CloseBlob(image) == MagickFalse)
296
0
    status=MagickFalse;
297
0
  return(status);
298
0
}