Coverage Report

Created: 2025-12-03 07:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/graphicsmagick/coders/braille.c
Line
Count
Source
1
/*
2
% Copyright (C) 2019 GraphicsMagick Group
3
%
4
% This program is covered by multiple licenses, which are described in
5
% Copyright.txt. You should have received a copy of Copyright.txt with this
6
% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
7
%
8
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9
%                                                                             %
10
%                                                                             %
11
%               BBBB   RRRR    AAA   IIIII  L      L      EEEEE               %
12
%               B   B  R   R  A   A    I    L      L      E                   %
13
%               BBBB   RRRR   AAAAA    I    L      L      EEE                 %
14
%               B   B  R R    A   A    I    L      L      E                   %
15
%               BBBB   R  R   A   A  IIIII  LLLLL  LLLLL  EEEEE               %
16
%                                                                             %
17
%                                                                             %
18
%                          Read/Write Braille Format                          %
19
%                                                                             %
20
%                               Samuel Thibault                               %
21
%                                February 2008                                %
22
%                                                                             %
23
%                                                                             %
24
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
25
%
26
%
27
*/
28

29
/*
30
  Include declarations.
31
*/
32
#include "magick/studio.h"
33
#include "magick/blob.h"
34
#include "magick/magick.h"
35
#include "magick/pixel_cache.h"
36
#include "magick/utility.h"
37

38
/*
39
  Forward declarations.
40
*/
41
static unsigned int
42
  WriteBRAILLEImage(const ImageInfo *,Image *);
43

44
/*
45
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
46
%                                                                             %
47
%                                                                             %
48
%                                                                             %
49
%   R e g i s t e r B R A I L L E I m a g e                                   %
50
%                                                                             %
51
%                                                                             %
52
%                                                                             %
53
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
54
%
55
%  RegisterBRAILLEImage() adds values for the Braille format to
56
%  the list of supported formats.  The values include the image format
57
%  tag, a method to read and/or write the format, whether the format
58
%  supports the saving of more than one frame to the same file or blob,
59
%  whether the format supports native in-memory I/O, and a brief
60
%  description of the format.
61
%
62
%  The format of the RegisterBRAILLEImage method is:
63
%
64
%      size_t RegisterBRAILLEImage(void)
65
%
66
*/
67
ModuleExport void RegisterBRAILLEImage(void)
68
0
{
69
0
  MagickInfo
70
0
    *entry;
71
72
0
  entry=SetMagickInfo("BRF");
73
0
  entry->encoder=(EncoderHandler) WriteBRAILLEImage;
74
0
  entry->adjoin=False;
75
0
  entry->description="BRF ASCII Braille format";
76
0
  entry->module="BRAILLE";
77
0
  (void) RegisterMagickInfo(entry);
78
0
  entry=SetMagickInfo("UBRL");
79
0
  entry->encoder=(EncoderHandler) WriteBRAILLEImage;
80
0
  entry->adjoin=False;
81
0
  entry->description="Unicode Text format";
82
0
  entry->module="BRAILLE";
83
0
  (void) RegisterMagickInfo(entry);
84
0
  entry=SetMagickInfo("UBRL6");
85
0
  entry->encoder=(EncoderHandler) WriteBRAILLEImage;
86
0
  entry->adjoin=False;
87
0
  entry->description="Unicode Text format 6dot";
88
0
  entry->module="BRAILLE";
89
0
  (void) RegisterMagickInfo(entry);
90
0
  entry=SetMagickInfo("ISOBRL");
91
0
  entry->encoder=(EncoderHandler) WriteBRAILLEImage;
92
0
  entry->adjoin=False;
93
0
  entry->description="ISO/TR 11548-1 format";
94
0
  entry->module="BRAILLE";
95
0
  (void) RegisterMagickInfo(entry);
96
0
  entry=SetMagickInfo("ISOBRL6");
97
0
  entry->encoder=(EncoderHandler) WriteBRAILLEImage;
98
0
  entry->adjoin=False;
99
0
  entry->description="ISO/TR 11548-1 format 6dot";
100
0
  entry->module="BRAILLE";
101
0
  (void) RegisterMagickInfo(entry);
102
0
}
103

104
/*
105
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
106
%                                                                             %
107
%                                                                             %
108
%                                                                             %
109
%   U n r e g i s t e r B R A I L L E I m a g e                               %
110
%                                                                             %
111
%                                                                             %
112
%                                                                             %
113
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
114
%
115
%  UnregisterBRAILLEImage() removes format registrations made by the
116
%  BRAILLE module from the list of supported formats.
117
%
118
%  The format of the UnregisterBRAILLEImage method is:
119
%
120
%      UnregisterBRAILLEImage(void)
121
%
122
*/
123
ModuleExport void UnregisterBRAILLEImage(void)
124
0
{
125
0
  (void) UnregisterMagickInfo("BRF");
126
0
  (void) UnregisterMagickInfo("UBRL");
127
0
  (void) UnregisterMagickInfo("UBRL6");
128
0
  (void) UnregisterMagickInfo("ISOBRL");
129
0
  (void) UnregisterMagickInfo("ISOBRL6");
130
0
}
131

132
/*
133
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
134
%                                                                             %
135
%                                                                             %
136
%                                                                             %
137
%   W r i t e B R A I L L E I m a g e                                         %
138
%                                                                             %
139
%                                                                             %
140
%                                                                             %
141
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
142
%
143
%  WriteBRAILLEImage() writes an image to a file in the Braille format.
144
%
145
%  The format of the WriteBRAILLEImage method is:
146
%
147
%      unsigned int WriteBRAILLEImage(const ImageInfo *image_info,
148
%        Image *image)
149
%
150
%  A description of each parameter follows.
151
%
152
%    o image_info: The image info.
153
%
154
%    o image:  The image.
155
%
156
*/
157
static unsigned int WriteBRAILLEImage(const ImageInfo *image_info,
158
  Image *image)
159
0
{
160
0
  char
161
0
    buffer[MaxTextExtent];
162
163
0
  IndexPacket
164
0
    polarity;
165
166
0
  int
167
0
    unicode = 0,
168
0
    iso_11548_1 = 0;
169
170
0
  unsigned int
171
0
    status;
172
173
0
  register const IndexPacket
174
0
    *indexes;
175
176
0
  register const PixelPacket
177
0
    *p;
178
179
0
  register unsigned long
180
0
    x;
181
182
0
  unsigned long
183
0
    cell_height = 4;
184
185
0
  unsigned long
186
0
    y;
187
188
  /*
189
    Open output image file.
190
  */
191
0
  assert(image_info != (const ImageInfo *) NULL);
192
0
  assert(image != (Image *) NULL);
193
0
  if (LocaleCompare(image_info->magick,"UBRL") == 0)
194
0
    unicode=1;
195
0
  else if (LocaleCompare(image_info->magick,"UBRL6") == 0)
196
0
    {
197
0
      unicode=1;
198
0
      cell_height=3;
199
0
    }
200
0
  else if (LocaleCompare(image_info->magick,"ISOBRL") == 0)
201
0
    iso_11548_1=1;
202
0
  else if (LocaleCompare(image_info->magick,"ISOBRL6") == 0)
203
0
    {
204
0
      iso_11548_1=1;
205
0
      cell_height=3;
206
0
    }
207
0
  else
208
0
    cell_height=3;
209
0
  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
210
0
  if (status == False)
211
0
    return(status);
212
0
  if (!iso_11548_1)
213
0
    {
214
0
      if (image->page.x != 0)
215
0
        {
216
0
          (void) FormatString(buffer,"X: %.20g\n",(double)
217
0
            image->page.x);
218
0
          (void) WriteBlobString(image,buffer);
219
0
        }
220
0
      if (image->page.y != 0)
221
0
        {
222
0
          (void) FormatString(buffer,"Y: %.20g\n",(double)
223
0
            image->page.y);
224
0
          (void) WriteBlobString(image,buffer);
225
0
        }
226
0
      (void) FormatString(buffer,"Width: %.20g\n",(double)
227
0
        image->columns+(image->columns % 2));
228
0
      (void) WriteBlobString(image,buffer);
229
0
      (void) FormatString(buffer,"Height: %.20g\n",(double)
230
0
        image->rows);
231
0
      (void) WriteBlobString(image,buffer);
232
0
      (void) WriteBlobString(image,"\n");
233
0
    }
234
0
  (void) SetImageType(image,BilevelType);
235
0
  polarity=PixelIntensityToQuantum(&image->colormap[0]) >= (MaxRGB/2);
236
0
  if (image->colors == 2)
237
0
    polarity=PixelIntensityToQuantum(&image->colormap[0]) >=
238
0
      PixelIntensityToQuantum(&image->colormap[1]);
239
0
  for (y=0; y < image->rows; y+=cell_height)
240
0
  {
241
0
    if ((y+cell_height) > image->rows)
242
0
      cell_height = (image->rows-y);
243
0
    p=AcquireImagePixels(image,0,y,image->columns,cell_height,&image->exception);
244
0
    if (p == (const PixelPacket *) NULL)
245
0
      break;
246
0
    indexes=AccessImmutableIndexes(image);
247
0
    for (x=0; x < image->columns; x+=2)
248
0
    {
249
0
      unsigned char cell = 0;
250
0
      unsigned long two_columns = x+1 < image->columns;
251
252
0
      do
253
0
      {
254
0
#define do_cell(dx,dy,bit) do { \
255
0
        cell |= (indexes[x+dx+dy*image->columns] == polarity) << bit; \
256
0
} while (0)
257
258
0
        do_cell(0,0,0);
259
0
        if (two_columns)
260
0
          do_cell(1,0,3);
261
0
        if (cell_height < 2)
262
0
          break;
263
264
0
        do_cell(0,1,1);
265
0
        if (two_columns)
266
0
          do_cell(1,1,4);
267
0
        if (cell_height < 3)
268
0
          break;
269
270
0
        do_cell(0,2,2);
271
0
        if (two_columns)
272
0
          do_cell(1,2,5);
273
0
        if (cell_height < 4)
274
0
          break;
275
276
0
        do_cell(0,3,6);
277
0
        if (two_columns)
278
0
          do_cell(1,3,7);
279
0
      } while(0);
280
281
0
      if (unicode)
282
0
        {
283
0
          unsigned char utf8[3];
284
          /* Unicode text */
285
0
          utf8[0] = (unsigned char) (0xe0|((0x28>>4)&0x0f));
286
0
          utf8[1] = 0x80|((0x28<<2)&0x3f)|(cell>>6);
287
0
          utf8[2] = 0x80|(cell&0x3f);
288
0
          (void) WriteBlob(image,3,utf8);
289
0
        }
290
0
      else if (iso_11548_1)
291
0
        {
292
          /* ISO/TR 11548-1 binary */
293
0
          (void) WriteBlobByte(image,cell);
294
0
        }
295
0
      else
296
0
        {
297
          /* BRF */
298
0
          static const unsigned char iso_to_brf[64] = {
299
0
            ' ', 'A', '1', 'B', '\'', 'K', '2', 'L',
300
0
            '@', 'C', 'I', 'F', '/', 'M', 'S', 'P',
301
0
            '"', 'E', '3', 'H', '9', 'O', '6', 'R',
302
0
            '^', 'D', 'J', 'G', '>', 'N', 'T', 'Q',
303
0
            ',', '*', '5', '<', '-', 'U', '8', 'V',
304
0
            '.', '%', '[', '$', '+', 'X', '!', '&',
305
0
            ';', ':', '4', '\\', '0', 'Z', '7', '(',
306
0
            '_', '?', 'W', ']', '#', 'Y', ')', '='
307
0
          };
308
0
          if (cell >= 64)
309
0
            cell = 0;
310
0
          (void) WriteBlobByte(image,iso_to_brf[cell]);
311
0
        }
312
0
    }
313
0
    if (iso_11548_1 == 0)
314
0
      (void) WriteBlobByte(image,'\n');
315
0
  }
316
0
  status &= CloseBlob(image);
317
0
  return(status);
318
0
}