1 /* 2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 % % 4 % % 5 % CCCC IIIII PPPP % 6 % C I P P % 7 % C I PPPP % 8 % C I P % 9 % CCCC IIIII P % 10 % % 11 % % 12 % Read/Write Cisco IP Phone Image Format % 13 % % 14 % Software Design % 15 % Cristy % 16 % April 2004 % 17 % % 18 % % 19 % Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization % 20 % dedicated to making software imaging solutions freely available. % 21 % % 22 % You may not use this file except in compliance with the License. You may % 23 % obtain a copy of the License at % 24 % % 25 % http://www.imagemagick.org/script/license.php % 26 % % 27 % Unless required by applicable law or agreed to in writing, software % 28 % distributed under the License is distributed on an "AS IS" BASIS, % 29 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % 30 % See the License for the specific language governing permissions and % 31 % limitations under the License. % 32 % % 33 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 34 % 35 % 36 */ 37 38 /* 40 Include declarations. 41 */ 42 #include "MagickCore/studio.h" 43 #include "MagickCore/blob.h" 44 #include "MagickCore/blob-private.h" 45 #include "MagickCore/cache.h" 46 #include "MagickCore/color-private.h" 47 #include "MagickCore/colorspace.h" 48 #include "MagickCore/colorspace-private.h" 49 #include "MagickCore/constitute.h" 50 #include "MagickCore/exception.h" 51 #include "MagickCore/exception-private.h" 52 #include "MagickCore/image.h" 53 #include "MagickCore/image-private.h" 54 #include "MagickCore/list.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/property.h" 61 #include "MagickCore/quantize.h" 62 #include "MagickCore/quantum-private.h" 63 #include "MagickCore/static.h" 64 #include "MagickCore/string_.h" 65 #include "MagickCore/module.h" 66 #include "MagickCore/utility.h" 67 68 /* 70 Forward declarations. 71 */ 72 static MagickBooleanType 73 WriteCIPImage(const ImageInfo *,Image *,ExceptionInfo *); 74 75 /* 77 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 78 % % 79 % % 80 % % 81 % R e g i s t e r C I P I m a g e % 82 % % 83 % % 84 % % 85 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 86 % 87 % RegisterCIPImage() adds properties for the CIP IP phone image format to 88 % the list of supported formats. The properties include the image format 89 % tag, a method to read and/or write the format, whether the format 90 % supports the saving of more than one frame to the same file or blob, 91 % whether the format supports native in-memory I/O, and a brief 92 % description of the format. 93 % 94 % The format of the RegisterCIPImage method is: 95 % 96 % size_t RegisterCIPImage(void) 97 % 98 */ 99 ModuleExport size_t RegisterCIPImage(void) 100 { 101 MagickInfo 102 *entry; 103 104 entry=AcquireMagickInfo("CIP","CIP","Cisco IP phone image format"); 105 entry->encoder=(EncodeImageHandler *) WriteCIPImage; 106 entry->flags^=CoderAdjoinFlag; 107 (void) RegisterMagickInfo(entry); 108 return(MagickImageCoderSignature); 109 } 110 111 /* 113 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 114 % % 115 % % 116 % % 117 % U n r e g i s t e r C I P I m a g e % 118 % % 119 % % 120 % % 121 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 122 % 123 % UnregisterCIPImage() removes format registrations made by the 124 % CIP module from the list of supported formats. 125 % 126 % The format of the UnregisterCIPImage method is: 127 % 128 % UnregisterCIPImage(void) 129 % 130 */ 131 ModuleExport void UnregisterCIPImage(void) 132 { 133 (void) UnregisterMagickInfo("CIP"); 134 } 135 136 /* 138 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 139 % % 140 % % 141 % % 142 % W r i t e C I P I m a g e % 143 % % 144 % % 145 % % 146 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 147 % 148 % Procedure WriteCIPImage() writes an image to a file in the Cisco IP phone 149 % image format. 150 % 151 % The format of the WriteCIPImage method is: 152 % 153 % MagickBooleanType WriteCIPImage(const ImageInfo *image_info, 154 % Image *image,ExceptionInfo *exception) 155 % 156 % A description of each parameter follows. 157 % 158 % o image_info: the image info. 159 % 160 % o image: The image. 161 % 162 % o exception: return any errors or warnings in this structure. 163 % 164 */ 165 static MagickBooleanType WriteCIPImage(const ImageInfo *image_info,Image *image, 166 ExceptionInfo *exception) 167 { 168 char 169 buffer[MagickPathExtent]; 170 171 const char 172 *value; 173 174 MagickBooleanType 175 status; 176 177 register const Quantum 178 *p; 179 180 register ssize_t 181 i, 182 x; 183 184 ssize_t 185 y; 186 187 unsigned char 188 byte; 189 190 /* 191 Open output image file. 192 */ 193 assert(image_info != (const ImageInfo *) NULL); 194 assert(image_info->signature == MagickCoreSignature); 195 assert(image != (Image *) NULL); 196 assert(image->signature == MagickCoreSignature); 197 if (image->debug != MagickFalse) 198 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 199 assert(exception != (ExceptionInfo *) NULL); 200 assert(exception->signature == MagickCoreSignature); 201 status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception); 202 if (status == MagickFalse) 203 return(status); 204 (void) WriteBlobString(image,"<CiscoIPPhoneImage>\n"); 205 value=GetImageProperty(image,"label",exception); 206 if (value != (const char *) NULL) 207 (void) FormatLocaleString(buffer,MagickPathExtent,"<Title>%s</Title>\n",value); 208 else 209 { 210 char 211 basename[MagickPathExtent]; 212 213 GetPathComponent(image->filename,BasePath,basename); 214 (void) FormatLocaleString(buffer,MagickPathExtent,"<Title>%s</Title>\n", 215 basename); 216 } 217 (void) WriteBlobString(image,buffer); 218 (void) FormatLocaleString(buffer,MagickPathExtent, 219 "<LocationX>%.20g</LocationX>\n",(double) image->page.x); 220 (void) WriteBlobString(image,buffer); 221 (void) FormatLocaleString(buffer,MagickPathExtent, 222 "<LocationY>%.20g</LocationY>\n",(double) image->page.y); 223 (void) WriteBlobString(image,buffer); 224 (void) FormatLocaleString(buffer,MagickPathExtent,"<Width>%.20g</Width>\n", 225 (double) (image->columns+(image->columns % 2))); 226 (void) WriteBlobString(image,buffer); 227 (void) FormatLocaleString(buffer,MagickPathExtent,"<Height>%.20g</Height>\n", 228 (double) image->rows); 229 (void) WriteBlobString(image,buffer); 230 (void) FormatLocaleString(buffer,MagickPathExtent,"<Depth>2</Depth>\n"); 231 (void) WriteBlobString(image,buffer); 232 (void) WriteBlobString(image,"<Data>"); 233 (void) TransformImageColorspace(image,sRGBColorspace,exception); 234 for (y=0; y < (ssize_t) image->rows; y++) 235 { 236 p=GetVirtualPixels(image,0,y,image->columns,1,exception); 237 if (p == (const Quantum *) NULL) 238 break; 239 for (x=0; x < ((ssize_t) image->columns-3); x+=4) 240 { 241 byte=(unsigned char) 242 ((((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+3))/QuantumRange) & 0x03) << 6) | 243 (((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+2))/QuantumRange) & 0x03) << 4) | 244 (((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+1))/QuantumRange) & 0x03) << 2) | 245 (((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+0))/QuantumRange) & 0x03) << 0)); 246 (void) FormatLocaleString(buffer,MagickPathExtent,"%02x",byte); 247 (void) WriteBlobString(image,buffer); 248 p+=4; 249 } 250 if ((image->columns % 4) != 0) 251 { 252 i=(ssize_t) image->columns % 4; 253 byte=(unsigned char) 254 ((((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+MagickMin(i,3)))/QuantumRange) & 0x03) << 6) | 255 (((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+MagickMin(i,2)))/QuantumRange) & 0x03) << 4) | 256 (((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+MagickMin(i,1)))/QuantumRange) & 0x03) << 2) | 257 (((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+MagickMin(i,0)))/QuantumRange) & 0x03) << 0)); 258 (void) FormatLocaleString(buffer,MagickPathExtent,"%02x",~byte); 259 (void) WriteBlobString(image,buffer); 260 } 261 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, 262 image->rows); 263 if (status == MagickFalse) 264 break; 265 } 266 (void) WriteBlobString(image,"</Data>\n"); 267 (void) WriteBlobString(image,"</CiscoIPPhoneImage>\n"); 268 (void) CloseBlob(image); 269 return(MagickTrue); 270 } 271