braille.c revision 79f189952032391bb2623c5efe0202152d9f0986
1/* 2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3% % 4% % 5% BBBB RRRR AAA IIIII L L EEEEE % 6% B B R R A A I L L E % 7% BBBB RRRR AAAAA I L L EEE % 8% B B R R A A I L L E % 9% BBBB R R A A IIIII LLLLL LLLLL EEEEE % 10% % 11% % 12% Read/Write Braille Format % 13% % 14% Samuel Thibault % 15% February 2008 % 16% % 17% % 18% Copyright 1999-2009 ImageMagick Studio LLC, a non-profit organization % 19% dedicated to making software imaging solutions freely available. % 20% % 21% You may not use this file except in compliance with the License. You may % 22% obtain a copy of the License at % 23% % 24% http://www.imagemagick.org/script/license.php % 25% % 26% Unless required by applicable law or agreed to in writing, software % 27% distributed under the License is distributed on an "AS IS" BASIS, % 28% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % 29% See the License for the specific language governing permissions and % 30% limitations under the License. % 31% % 32%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 33% 34% 35*/ 36 37/* 38 Include declarations. 39*/ 40#include "magick/studio.h" 41#include "magick/blob.h" 42#include "magick/blob-private.h" 43#include "magick/cache.h" 44#include "magick/color-private.h" 45#include "magick/colorspace.h" 46#include "magick/constitute.h" 47#include "magick/exception.h" 48#include "magick/exception-private.h" 49#include "magick/image.h" 50#include "magick/image-private.h" 51#include "magick/list.h" 52#include "magick/magick.h" 53#include "magick/memory_.h" 54#include "magick/module.h" 55#include "magick/monitor.h" 56#include "magick/monitor-private.h" 57#include "magick/property.h" 58#include "magick/quantize.h" 59#include "magick/static.h" 60#include "magick/string_.h" 61#include "magick/utility.h" 62 63/* 64 Forward declarations. 65*/ 66static MagickBooleanType 67 WriteBRAILLEImage(const ImageInfo *,Image *); 68 69/* 70%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 71% % 72% % 73% % 74% R e g i s t e r B R A I L L E I m a g e % 75% % 76% % 77% % 78%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 79% 80% RegisterBRAILLEImage() adds values for the Braille format to 81% the list of supported formats. The values include the image format 82% tag, a method to read and/or write the format, whether the format 83% supports the saving of more than one frame to the same file or blob, 84% whether the format supports native in-memory I/O, and a brief 85% description of the format. 86% 87% The format of the RegisterBRAILLEImage method is: 88% 89% unsigned long RegisterBRAILLEImage(void) 90% 91*/ 92ModuleExport unsigned long RegisterBRAILLEImage(void) 93{ 94 MagickInfo 95 *entry; 96 97 entry=SetMagickInfo("BRF"); 98 entry->encoder=(EncodeImageHandler *) WriteBRAILLEImage; 99 entry->adjoin=MagickFalse; 100 entry->description=AcquireString("BRF ASCII Braille format"); 101 entry->module=AcquireString("BRAILLE"); 102 (void) RegisterMagickInfo(entry); 103 entry=SetMagickInfo("UBRL"); 104 entry->encoder=(EncodeImageHandler *) WriteBRAILLEImage; 105 entry->adjoin=MagickFalse; 106 entry->description=AcquireString("Unicode Text format"); 107 entry->module=AcquireString("BRAILLE"); 108 (void) RegisterMagickInfo(entry); 109 entry=SetMagickInfo("ISOBRL"); 110 entry->encoder=(EncodeImageHandler *) WriteBRAILLEImage; 111 entry->adjoin=MagickFalse; 112 entry->description=AcquireString("ISO/TR 11548-1 format"); 113 entry->module=AcquireString("BRAILLE"); 114 (void) RegisterMagickInfo(entry); 115 return(MagickImageCoderSignature); 116} 117 118/* 119%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 120% % 121% % 122% % 123% U n r e g i s t e r B R A I L L E I m a g e % 124% % 125% % 126% % 127%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 128% 129% UnregisterBRAILLEImage() removes format registrations made by the 130% BRAILLE module from the list of supported formats. 131% 132% The format of the UnregisterBRAILLEImage method is: 133% 134% UnregisterBRAILLEImage(void) 135% 136*/ 137ModuleExport void UnregisterBRAILLEImage(void) 138{ 139 (void) UnregisterMagickInfo("BRF"); 140 (void) UnregisterMagickInfo("UBRL"); 141 (void) UnregisterMagickInfo("ISOBRL"); 142} 143 144/* 145%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 146% % 147% % 148% % 149% W r i t e B R A I L L E I m a g e % 150% % 151% % 152% % 153%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 154% 155% WriteBRAILLEImage() writes an image to a file in the Braille format. 156% 157% The format of the WriteBRAILLEImage method is: 158% 159% MagickBooleanType WriteBRAILLEImage(const ImageInfo *image_info, 160% Image *image) 161% 162% A description of each parameter follows. 163% 164% o image_info: The image info. 165% 166% o image: The image. 167% 168*/ 169static MagickBooleanType WriteBRAILLEImage(const ImageInfo *image_info, 170 Image *image) 171{ 172 char 173 buffer[MaxTextExtent]; 174 175 const char 176 *value; 177 178 int 179 unicode = 0, 180 iso_11548_1 = 0; 181 182 long 183 y; 184 185 MagickBooleanType 186 status; 187 188 register const IndexPacket 189 *indexes; 190 191 register const PixelPacket 192 *p; 193 194 IndexPacket 195 polarity; 196 197 register long 198 x; 199 200 unsigned long 201 cell_height = 4; 202 203 /* 204 Open output image file. 205 */ 206 assert(image_info != (const ImageInfo *) NULL); 207 assert(image_info->signature == MagickSignature); 208 assert(image != (Image *) NULL); 209 assert(image->signature == MagickSignature); 210 if (LocaleCompare(image_info->magick, "UBRL") == 0) 211 unicode=1; 212 else 213 if (LocaleCompare(image_info->magick, "ISOBRL") == 0) 214 iso_11548_1=1; 215 else 216 cell_height=3; 217 if (image->debug != MagickFalse) 218 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 219 status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); 220 if (status == MagickFalse) 221 return(status); 222 if (!iso_11548_1) 223 { 224 value=GetImageProperty(image,"Label"); 225 if (value != (const char *) NULL) { 226 (void) FormatMagickString(buffer,MaxTextExtent,"Title: %s\n", value); 227 (void) WriteBlobString(image,buffer); 228 } 229 if (image->page.x) 230 { 231 (void) FormatMagickString(buffer,MaxTextExtent,"X: %ld\n", 232 image->page.x); 233 (void) WriteBlobString(image,buffer); 234 } 235 if (image->page.y) 236 { 237 (void) FormatMagickString(buffer,MaxTextExtent,"Y: %ld\n", 238 image->page.y); 239 (void) WriteBlobString(image,buffer); 240 } 241 (void) FormatMagickString(buffer,MaxTextExtent,"Width: %lu\n", 242 image->columns+(image->columns % 2)); 243 (void) WriteBlobString(image,buffer); 244 (void) FormatMagickString(buffer,MaxTextExtent,"Height: %lu\n", 245 image->rows); 246 (void) WriteBlobString(image,buffer); 247 (void) WriteBlobString(image,"\n"); 248 } 249 (void) SetImageType(image,BilevelType); 250 polarity = 0; 251 if (image->storage_class == PseudoClass) { 252 polarity=(IndexPacket) (PixelIntensityToQuantum(&image->colormap[0]) >= 253 (Quantum) (QuantumRange/2)); 254 if (image->colors == 2) 255 polarity=(IndexPacket) 256 (PixelIntensityToQuantum(&image->colormap[0]) >= 257 PixelIntensityToQuantum(&image->colormap[1])); 258 } 259 for (y=0; y < (long) image->rows; y+=cell_height) 260 { 261 if ((y+cell_height) > image->rows) 262 cell_height = (unsigned long) (image->rows-y); 263 264 p=GetVirtualPixels(image,0,y,image->columns,cell_height,&image->exception); 265 if (p == (const PixelPacket *) NULL) 266 break; 267 indexes=GetVirtualIndexQueue(image); 268 for (x=0; x < (long) image->columns; x+=2) 269 { 270 unsigned char cell = 0; 271 int two_columns = x+1 < (long) image->columns; 272 273 do 274 { 275#define do_cell(dx,dy,bit) do { \ 276 if (image->storage_class == PseudoClass) \ 277 cell |= (indexes[x+dx+dy*image->columns] == polarity) << bit; \ 278 else \ 279 cell |= (p[x+dx+dy*image->columns].green == 0) << bit; \ 280} while (0) 281 282 do_cell(0,0,0); 283 if (two_columns) 284 do_cell(1,0,3); 285 if (cell_height < 2) 286 break; 287 288 do_cell(0,1,1); 289 if (two_columns) 290 do_cell(1,1,4); 291 if (cell_height < 3) 292 break; 293 294 do_cell(0,2,2); 295 if (two_columns) 296 do_cell(1,2,5); 297 if (cell_height < 4) 298 break; 299 300 do_cell(0,3,6); 301 if (two_columns) 302 do_cell(1,3,7); 303 } while(0); 304 305 if (unicode) 306 { 307 unsigned char utf8[3]; 308 /* Unicode text */ 309 utf8[0] = (unsigned char) (0xe0|((0x28>>4)&0x0f)); 310 utf8[1] = 0x80|((0x28<<2)&0x3f)|(cell>>6); 311 utf8[2] = 0x80|(cell&0x3f); 312 (void) WriteBlob(image,3,utf8); 313 } 314 else if (iso_11548_1) 315 { 316 /* ISO/TR 11548-1 binary */ 317 (void) WriteBlobByte(image,cell); 318 } 319 else 320 { 321 /* BRF */ 322 static const unsigned char iso_to_brf[64] = { 323 ' ', 'A', '1', 'B', '\'', 'K', '2', 'L', 324 '@', 'C', 'I', 'F', '/', 'M', 'S', 'P', 325 '"', 'E', '3', 'H', '9', 'O', '6', 'R', 326 '^', 'D', 'J', 'G', '>', 'N', 'T', 'Q', 327 ',', '*', '5', '<', '-', 'U', '8', 'V', 328 '.', '%', '[', '$', '+', 'X', '!', '&', 329 ';', ':', '4', '\\', '0', 'Z', '7', '(', 330 '_', '?', 'W', ']', '#', 'Y', ')', '=' 331 }; 332 (void) WriteBlobByte(image,iso_to_brf[cell]); 333 } 334 } 335 if (!iso_11548_1) 336 (void) WriteBlobByte(image,'\n'); 337 status=SetImageProgress(image,SaveImageTag,y,image->rows); 338 if (status == MagickFalse) 339 break; 340 } 341 (void) CloseBlob(image); 342 return(MagickTrue); 343} 344