Coverage Report

Created: 2026-01-20 07:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/graphicsmagick/coders/uil.c
Line
Count
Source
1
/*
2
% Copyright (C) 2003-2025 GraphicsMagick Group
3
% Copyright (C) 2002 ImageMagick Studio
4
% Copyright 1991-1999 E. I. du Pont de Nemours and Company
5
%
6
% This program is covered by multiple licenses, which are described in
7
% Copyright.txt. You should have received a copy of Copyright.txt with this
8
% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
9
%
10
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11
%                                                                             %
12
%                                                                             %
13
%                                                                             %
14
%                            U   U  IIIII  L                                  %
15
%                            U   U    I    L                                  %
16
%                            U   U    I    L                                  %
17
%                            U   U    I    L                                  %
18
%                             UUU   IIIII  LLLLL                              %
19
%                                                                             %
20
%                                                                             %
21
%                         Write X-Motif UIL Table                             %
22
%                                                                             %
23
%                                                                             %
24
%                              Software Design                                %
25
%                                John Cristy                                  %
26
%                                 July 1992                                   %
27
%                                                                             %
28
%                                                                             %
29
%                                                                             %
30
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
31
%
32
%
33
*/
34

35
/*
36
  Include declarations.
37
*/
38
#include "magick/studio.h"
39
#include "magick/blob.h"
40
#include "magick/pixel_cache.h"
41
#include "magick/color.h"
42
#include "magick/color_lookup.h"
43
#include "magick/magick.h"
44
#include "magick/monitor.h"
45
#include "magick/utility.h"
46
#include "magick/static.h"
47

48
/*
49
  Forward declarations.
50
*/
51
static unsigned int
52
  WriteUILImage(const ImageInfo *,Image *);
53

54
/*
55
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
56
%                                                                             %
57
%                                                                             %
58
%                                                                             %
59
%   R e g i s t e r U I L I m a g e                                           %
60
%                                                                             %
61
%                                                                             %
62
%                                                                             %
63
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
64
%
65
%  Method RegisterUILImage adds attributes for the UIL image format to
66
%  the list of supported formats.  The attributes include the image format
67
%  tag, a method to read and/or write the format, whether the format
68
%  supports the saving of more than one frame to the same file or blob,
69
%  whether the format supports native in-memory I/O, and a brief
70
%  description of the format.
71
%
72
%  The format of the RegisterUILImage method is:
73
%
74
%      RegisterUILImage(void)
75
%
76
*/
77
ModuleExport void RegisterUILImage(void)
78
0
{
79
0
  MagickInfo
80
0
    *entry;
81
82
0
  entry=SetMagickInfo("UIL");
83
0
  entry->encoder=(EncoderHandler) WriteUILImage;
84
0
  entry->adjoin=False;
85
0
  entry->description="X-Motif UIL table";
86
0
  entry->module="UIL";
87
0
  entry->coder_class=UnstableCoderClass;
88
0
  (void) RegisterMagickInfo(entry);
89
0
}
90

91
/*
92
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
93
%                                                                             %
94
%                                                                             %
95
%                                                                             %
96
%   U n r e g i s t e r U I L I m a g e                                       %
97
%                                                                             %
98
%                                                                             %
99
%                                                                             %
100
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
101
%
102
%  Method UnregisterUILImage removes format registrations made by the
103
%  UIL module from the list of supported formats.
104
%
105
%  The format of the UnregisterUILImage method is:
106
%
107
%      UnregisterUILImage(void)
108
%
109
*/
110
ModuleExport void UnregisterUILImage(void)
111
0
{
112
0
  (void) UnregisterMagickInfo("UIL");
113
0
}
114

115
/*
116
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
117
%                                                                             %
118
%                                                                             %
119
%                                                                             %
120
%   W r i t e U I L I m a g e                                                 %
121
%                                                                             %
122
%                                                                             %
123
%                                                                             %
124
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
125
%
126
%  Procedure WriteUILImage writes an image to a file in the X-Motif UIL table
127
%  format.
128
%
129
%  The format of the WriteUILImage method is:
130
%
131
%      unsigned int WriteUILImage(const ImageInfo *image_info,Image *image)
132
%
133
%  A description of each parameter follows.
134
%
135
%    o status: Method WriteUILImage return True if the image is written.
136
%      False is returned is there is a memory shortage or if the image file
137
%      fails to write.
138
%
139
%    o image_info: Specifies a pointer to a ImageInfo structure.
140
%
141
%    o image:  A pointer to an Image structure.
142
%
143
%
144
*/
145
static unsigned int WriteUILImage(const ImageInfo *image_info,Image *image)
146
0
{
147
0
#define MaxCixels  92
148
149
0
  static const char
150
0
    Cixel[MaxCixels+1] = " .XoO+@#$%&*=-;:>,<1234567890qwertyuipasdfghjk"
151
0
                         "lzxcvbnmMNBVCZASDFGHJKLPIUYTREWQ!~^/()_`'][{}|";
152
153
0
  char
154
0
    basename[MaxTextExtent],
155
0
    buffer[MaxTextExtent],
156
0
    name[MaxTextExtent],
157
0
    symbol[MaxTextExtent];
158
159
0
  int
160
0
    j;
161
162
0
  long
163
0
    k,
164
0
    y;
165
166
0
  register const PixelPacket
167
0
    *p;
168
169
0
  register long
170
0
    i,
171
0
    x;
172
173
0
  unsigned int
174
0
    status,
175
0
    transparent;
176
177
0
  unsigned long
178
0
    characters_per_pixel,
179
0
    colors,
180
0
    number_pixels;
181
182
  /*
183
    Open output image file.
184
  */
185
0
  assert(image_info != (const ImageInfo *) NULL);
186
0
  assert(image_info->signature == MagickSignature);
187
0
  assert(image != (Image *) NULL);
188
0
  assert(image->signature == MagickSignature);
189
0
  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
190
0
  if (status == False)
191
0
    ThrowWriterException(FileOpenError,UnableToOpenFile,image);
192
0
  (void) TransformColorspace(image,RGBColorspace);
193
0
  transparent=False;
194
0
  i=0;
195
0
  p=(const PixelPacket *) NULL;
196
0
  if (image->storage_class == PseudoClass)
197
0
    colors=image->colors;
198
0
  else
199
0
    {
200
0
      unsigned char
201
0
        *matte_image;
202
203
      /*
204
        Convert DirectClass to PseudoClass image.
205
      */
206
0
      matte_image=(unsigned char *) NULL;
207
0
      if (image->matte)
208
0
        {
209
          /*
210
            Map all the transparent pixels.
211
          */
212
0
          number_pixels=image->columns*image->rows;
213
0
          matte_image=MagickAllocateResourceLimitedMemory(unsigned char *,number_pixels);
214
0
          if (matte_image == (unsigned char *) NULL)
215
0
            ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,
216
0
              image);
217
0
          for (y=0; y < (long) image->rows; y++)
218
0
          {
219
0
            p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
220
0
            if (p == (const PixelPacket *) NULL)
221
0
              break;
222
0
            for (x=0; x < (long) image->columns; x++)
223
0
            {
224
0
              matte_image[i]=(unsigned char) (p->opacity == TransparentOpacity);
225
0
              if (matte_image[i])
226
0
                transparent=True;
227
0
              i++;
228
0
              p++;
229
0
            }
230
0
          }
231
0
        }
232
0
      (void) SetImageType(image,PaletteType);
233
0
      colors=image->colors;
234
0
      if (transparent)
235
0
        {
236
0
          i=0;
237
0
          colors++;
238
0
          for (y=0; y < (long) image->rows; y++)
239
0
          {
240
0
            register IndexPacket
241
0
              *indexes;
242
243
0
            p=GetImagePixelsEx(image,0,y,image->columns,1,&image->exception);
244
0
            if (p == (const PixelPacket *) NULL)
245
0
              break;
246
0
            indexes=AccessMutableIndexes(image);
247
0
            for (x=0; x < (long) image->columns; x++)
248
0
            {
249
0
              if (matte_image[i])
250
0
                indexes[x]=(IndexPacket) image->colors;
251
0
              p++;
252
0
            }
253
0
          }
254
0
        }
255
0
      if (matte_image != (unsigned char *) NULL)
256
0
        MagickFreeResourceLimitedMemory(unsigned char *,matte_image);
257
0
    }
258
  /*
259
    Compute the character per pixel.
260
  */
261
0
  characters_per_pixel=1;
262
0
  for (k=MaxCixels; (long) colors > k; k*=MaxCixels)
263
0
    characters_per_pixel++;
264
  /*
265
    UIL header.
266
  */
267
0
  (void) WriteBlobString(image,"/* UIL */\n");
268
0
  GetPathComponent(image->filename,BasePath,basename);
269
0
  FormatString(buffer,"value\n  %.1024s_ct : color_table(\n",basename);
270
0
  (void) WriteBlobString(image,buffer);
271
0
  for (i=0; i < (long) image->colors; i++)
272
0
  {
273
    /*
274
      Define UIL color.
275
    */
276
0
    (void) QueryColorname(image,image->colormap+i,X11Compliance,name,
277
0
      &image->exception);
278
0
    if (transparent)
279
0
      if (i == (long) (colors-1))
280
0
        (void) strlcpy(name,"None",sizeof(name));
281
    /*
282
      Write UIL color.
283
    */
284
0
    k=i % MaxCixels;
285
0
    symbol[0]=Cixel[k];
286
0
    for (j=1; j < (int) characters_per_pixel; j++)
287
0
    {
288
0
      k=((i-k)/MaxCixels) % MaxCixels;
289
0
      symbol[j]=Cixel[k];
290
0
    }
291
0
    symbol[j]='\0';
292
0
    if (LocaleCompare(name,"None") == 0)
293
0
      FormatString(buffer,"    background color = '%.1024s'",symbol);
294
0
    else
295
0
      FormatString(buffer,"    color('%.1024s',%.1024s) = '%.1024s'",name,
296
0
        PixelIntensityToQuantum(image->colormap+i) < (((double) MaxRGB+1.0)/2.0) ?
297
0
        "background" : "foreground",symbol);
298
0
    (void) WriteBlobString(image,buffer);
299
0
    FormatString(buffer,"%.1024s",(i == (long) (colors-1) ? ");\n" : ",\n"));
300
0
    (void) WriteBlobString(image,buffer);
301
0
  }
302
  /*
303
    Define UIL pixels.
304
  */
305
0
  GetPathComponent(image->filename,BasePath,basename);
306
0
  FormatString(buffer,
307
0
    "  %.1024s_icon : icon(color_table = %.1024s_ct,\n",basename,basename);
308
0
  (void) WriteBlobString(image,buffer);
309
0
  for (y=0; y < (long) image->rows; y++)
310
0
  {
311
0
    register const IndexPacket
312
0
      *indexes;
313
314
0
    p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
315
0
    if (p == (const PixelPacket *) NULL)
316
0
      break;
317
0
    indexes=AccessImmutableIndexes(image);
318
0
    (void) WriteBlobString(image,"    \"");
319
0
    for (x=0; x < (long) image->columns; x++)
320
0
    {
321
0
      k=(long) (indexes[x] % MaxCixels);
322
0
      symbol[0]=Cixel[k];
323
0
      for (j=1; j < (int) characters_per_pixel; j++)
324
0
      {
325
0
        k=(((int) indexes[x]-k)/MaxCixels) % MaxCixels;
326
0
        symbol[j]=Cixel[k];
327
0
      }
328
0
      symbol[j]='\0';
329
0
      (void) strlcpy(buffer,symbol,MaxTextExtent);
330
0
      (void) WriteBlobString(image,buffer);
331
0
      p++;
332
0
    }
333
0
    FormatString(buffer,"\"%.1024s\n",
334
0
      (y == (long) (image->rows-1) ? ");" : ","));
335
0
    (void) WriteBlobString(image,buffer);
336
0
    if (QuantumTick(y,image->rows))
337
0
      if (!MagickMonitorFormatted(y,image->rows,&image->exception,
338
0
                                  SaveImageText,image->filename,
339
0
                                  image->columns,image->rows))
340
0
        break;
341
0
  }
342
0
  status &= CloseBlob(image);
343
0
  return(status);
344
0
}