1 /* 2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 % % 4 % % 5 % % 6 % U U IIIII L % 7 % U U I L % 8 % U U I L % 9 % U U I L % 10 % UUU IIIII LLLLL % 11 % % 12 % % 13 % Write X-Motif UIL Table. % 14 % % 15 % Software Design % 16 % Cristy % 17 % July 1992 % 18 % % 19 % % 20 % Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization % 21 % dedicated to making software imaging solutions freely available. % 22 % % 23 % You may not use this file except in compliance with the License. You may % 24 % obtain a copy of the License at % 25 % % 26 % http://www.imagemagick.org/script/license.php % 27 % % 28 % Unless required by applicable law or agreed to in writing, software % 29 % distributed under the License is distributed on an "AS IS" BASIS, % 30 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % 31 % See the License for the specific language governing permissions and % 32 % limitations under the License. % 33 % % 34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 35 % 36 % 37 */ 38 39 /* 41 Include declarations. 42 */ 43 #include "MagickCore/studio.h" 44 #include "MagickCore/attribute.h" 45 #include "MagickCore/blob.h" 46 #include "MagickCore/blob-private.h" 47 #include "MagickCore/cache.h" 48 #include "MagickCore/color.h" 49 #include "MagickCore/color-private.h" 50 #include "MagickCore/colorspace.h" 51 #include "MagickCore/colorspace-private.h" 52 #include "MagickCore/exception.h" 53 #include "MagickCore/exception-private.h" 54 #include "MagickCore/image-private.h" 55 #include "MagickCore/magick.h" 56 #include "MagickCore/memory_.h" 57 #include "MagickCore/monitor.h" 58 #include "MagickCore/monitor-private.h" 59 #include "MagickCore/pixel-accessor.h" 60 #include "MagickCore/quantum-private.h" 61 #include "MagickCore/static.h" 62 #include "MagickCore/string_.h" 63 #include "MagickCore/module.h" 64 #include "MagickCore/utility.h" 65 66 /* 68 Forward declarations. 69 */ 70 static MagickBooleanType 71 WriteUILImage(const ImageInfo *,Image *,ExceptionInfo *); 72 73 /* 75 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 76 % % 77 % % 78 % % 79 % R e g i s t e r U I L I m a g e % 80 % % 81 % % 82 % % 83 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 84 % 85 % RegisterUILImage() adds attributes for the UIL image format to 86 % the list of supported formats. The attributes include the image format 87 % tag, a method to read and/or write the format, whether the format 88 % supports the saving of more than one frame to the same file or blob, 89 % whether the format supports native in-memory I/O, and a brief 90 % description of the format. 91 % 92 % The format of the RegisterUILImage method is: 93 % 94 % size_t RegisterUILImage(void) 95 % 96 */ 97 ModuleExport size_t RegisterUILImage(void) 98 { 99 MagickInfo 100 *entry; 101 102 entry=AcquireMagickInfo("UIL","UIL","X-Motif UIL table"); 103 entry->encoder=(EncodeImageHandler *) WriteUILImage; 104 entry->flags^=CoderAdjoinFlag; 105 (void) RegisterMagickInfo(entry); 106 return(MagickImageCoderSignature); 107 } 108 109 /* 111 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 112 % % 113 % % 114 % % 115 % U n r e g i s t e r U I L I m a g e % 116 % % 117 % % 118 % % 119 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 120 % 121 % UnregisterUILImage() removes format registrations made by the 122 % UIL module from the list of supported formats. 123 % 124 % The format of the UnregisterUILImage method is: 125 % 126 % UnregisterUILImage(void) 127 % 128 */ 129 ModuleExport void UnregisterUILImage(void) 130 { 131 (void) UnregisterMagickInfo("UIL"); 132 } 133 134 /* 136 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 137 % % 138 % % 139 % % 140 % W r i t e U I L I m a g e % 141 % % 142 % % 143 % % 144 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 145 % 146 % Procedure WriteUILImage() writes an image to a file in the X-Motif UIL table 147 % format. 148 % 149 % The format of the WriteUILImage method is: 150 % 151 % MagickBooleanType WriteUILImage(const ImageInfo *image_info, 152 % Image *image,ExceptionInfo *exception) 153 % 154 % A description of each parameter follows. 155 % 156 % o image_info: the image info. 157 % 158 % o image: The image. 159 % 160 % o exception: return any errors or warnings in this structure. 161 % 162 */ 163 static MagickBooleanType WriteUILImage(const ImageInfo *image_info,Image *image, 164 ExceptionInfo *exception) 165 { 166 #define MaxCixels 92 167 168 char 169 basename[MagickPathExtent], 170 buffer[MagickPathExtent], 171 name[MagickPathExtent], 172 *symbol; 173 174 int 175 j; 176 177 MagickBooleanType 178 status, 179 transparent; 180 181 MagickSizeType 182 number_pixels; 183 184 PixelInfo 185 pixel; 186 187 register const Quantum 188 *p; 189 190 register ssize_t 191 i, 192 x; 193 194 size_t 195 characters_per_pixel, 196 colors; 197 198 ssize_t 199 k, 200 y; 201 202 static const char 203 Cixel[MaxCixels+1] = " .XoO+@#$%&*=-;:>,<1234567890qwertyuipasdfghjk" 204 "lzxcvbnmMNBVCZASDFGHJKLPIUYTREWQ!~^/()_`'][{}|"; 205 206 /* 207 Open output image file. 208 */ 209 assert(image_info != (const ImageInfo *) NULL); 210 assert(image_info->signature == MagickCoreSignature); 211 assert(image != (Image *) NULL); 212 assert(image->signature == MagickCoreSignature); 213 if (image->debug != MagickFalse) 214 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 215 assert(exception != (ExceptionInfo *) NULL); 216 assert(exception->signature == MagickCoreSignature); 217 status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception); 218 if (status == MagickFalse) 219 return(status); 220 (void) TransformImageColorspace(image,sRGBColorspace,exception); 221 transparent=MagickFalse; 222 i=0; 223 p=(const Quantum *) NULL; 224 if (image->storage_class == PseudoClass) 225 colors=image->colors; 226 else 227 { 228 unsigned char 229 *matte_image; 230 231 /* 232 Convert DirectClass to PseudoClass image. 233 */ 234 matte_image=(unsigned char *) NULL; 235 if (image->alpha_trait != UndefinedPixelTrait) 236 { 237 /* 238 Map all the transparent pixels. 239 */ 240 number_pixels=(MagickSizeType) image->columns*image->rows; 241 if (number_pixels != ((MagickSizeType) (size_t) number_pixels)) 242 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); 243 matte_image=(unsigned char *) AcquireQuantumMemory(image->columns, 244 image->rows*sizeof(*matte_image)); 245 if (matte_image == (unsigned char *) NULL) 246 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); 247 for (y=0; y < (ssize_t) image->rows; y++) 248 { 249 p=GetVirtualPixels(image,0,y,image->columns,1,exception); 250 if (p == (const Quantum *) NULL) 251 break; 252 for (x=0; x < (ssize_t) image->columns; x++) 253 { 254 matte_image[i]=(unsigned char) (GetPixelAlpha(image,p) == 255 (Quantum) TransparentAlpha ? 1 : 0); 256 if (matte_image[i] != 0) 257 transparent=MagickTrue; 258 i++; 259 p+=GetPixelChannels(image); 260 } 261 } 262 } 263 (void) SetImageType(image,PaletteType,exception); 264 colors=image->colors; 265 if (transparent != MagickFalse) 266 { 267 register Quantum 268 *q; 269 270 colors++; 271 for (y=0; y < (ssize_t) image->rows; y++) 272 { 273 q=GetAuthenticPixels(image,0,y,image->columns,1,exception); 274 if (q == (Quantum *) NULL) 275 break; 276 for (x=0; x < (ssize_t) image->columns; x++) 277 { 278 if (matte_image[i] != 0) 279 SetPixelIndex(image,(Quantum) image->colors,q); 280 q+=GetPixelChannels(image); 281 } 282 } 283 } 284 if (matte_image != (unsigned char *) NULL) 285 matte_image=(unsigned char *) RelinquishMagickMemory(matte_image); 286 } 287 /* 288 Compute the character per pixel. 289 */ 290 characters_per_pixel=1; 291 for (k=MaxCixels; (ssize_t) colors > k; k*=MaxCixels) 292 characters_per_pixel++; 293 /* 294 UIL header. 295 */ 296 symbol=AcquireString(""); 297 (void) WriteBlobString(image,"/* UIL */\n"); 298 GetPathComponent(image->filename,BasePath,basename); 299 (void) FormatLocaleString(buffer,MagickPathExtent, 300 "value\n %s_ct : color_table(\n",basename); 301 (void) WriteBlobString(image,buffer); 302 GetPixelInfo(image,&pixel); 303 for (i=0; i < (ssize_t) colors; i++) 304 { 305 /* 306 Define UIL color. 307 */ 308 pixel=image->colormap[i]; 309 pixel.colorspace=sRGBColorspace; 310 pixel.depth=8; 311 pixel.alpha=(double) OpaqueAlpha; 312 GetColorTuple(&pixel,MagickTrue,name); 313 if (transparent != MagickFalse) 314 if (i == (ssize_t) (colors-1)) 315 (void) CopyMagickString(name,"None",MagickPathExtent); 316 /* 317 Write UIL color. 318 */ 319 k=i % MaxCixels; 320 symbol[0]=Cixel[k]; 321 for (j=1; j < (int) characters_per_pixel; j++) 322 { 323 k=((i-k)/MaxCixels) % MaxCixels; 324 symbol[j]=Cixel[k]; 325 } 326 symbol[j]='\0'; 327 (void) SubstituteString(&symbol,"'","''"); 328 if (LocaleCompare(name,"None") == 0) 329 (void) FormatLocaleString(buffer,MagickPathExtent, 330 " background color = '%s'",symbol); 331 else 332 (void) FormatLocaleString(buffer,MagickPathExtent, 333 " color('%s',%s) = '%s'",name, 334 GetPixelInfoIntensity(image,image->colormap+i) < 335 (QuantumRange/2.0) ? "background" : "foreground",symbol); 336 (void) WriteBlobString(image,buffer); 337 (void) FormatLocaleString(buffer,MagickPathExtent,"%s", 338 (i == (ssize_t) (colors-1) ? ");\n" : ",\n")); 339 (void) WriteBlobString(image,buffer); 340 } 341 /* 342 Define UIL pixels. 343 */ 344 GetPathComponent(image->filename,BasePath,basename); 345 (void) FormatLocaleString(buffer,MagickPathExtent, 346 " %s_icon : icon(color_table = %s_ct,\n",basename,basename); 347 (void) WriteBlobString(image,buffer); 348 for (y=0; y < (ssize_t) image->rows; y++) 349 { 350 p=GetVirtualPixels(image,0,y,image->columns,1,exception); 351 if (p == (const Quantum *) NULL) 352 break; 353 (void) WriteBlobString(image," \""); 354 for (x=0; x < (ssize_t) image->columns; x++) 355 { 356 k=((ssize_t) GetPixelIndex(image,p) % MaxCixels); 357 symbol[0]=Cixel[k]; 358 for (j=1; j < (int) characters_per_pixel; j++) 359 { 360 k=(((int) GetPixelIndex(image,p)-k)/MaxCixels) % 361 MaxCixels; 362 symbol[j]=Cixel[k]; 363 } 364 symbol[j]='\0'; 365 (void) CopyMagickString(buffer,symbol,MagickPathExtent); 366 (void) WriteBlobString(image,buffer); 367 p+=GetPixelChannels(image); 368 } 369 (void) FormatLocaleString(buffer,MagickPathExtent,"\"%s\n", 370 (y == (ssize_t) (image->rows-1) ? ");" : ",")); 371 (void) WriteBlobString(image,buffer); 372 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, 373 image->rows); 374 if (status == MagickFalse) 375 break; 376 } 377 symbol=DestroyString(symbol); 378 (void) CloseBlob(image); 379 return(MagickTrue); 380 } 381