Coverage Report

Created: 2025-07-23 08:18

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