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/* 39 Include declarations. 40*/ 41#include "MagickCore/studio.h" 42#include "MagickCore/blob.h" 43#include "MagickCore/blob-private.h" 44#include "MagickCore/cache.h" 45#include "MagickCore/color-private.h" 46#include "MagickCore/colorspace.h" 47#include "MagickCore/colorspace-private.h" 48#include "MagickCore/constitute.h" 49#include "MagickCore/exception.h" 50#include "MagickCore/exception-private.h" 51#include "MagickCore/image.h" 52#include "MagickCore/image-private.h" 53#include "MagickCore/list.h" 54#include "MagickCore/magick.h" 55#include "MagickCore/memory_.h" 56#include "MagickCore/monitor.h" 57#include "MagickCore/monitor-private.h" 58#include "MagickCore/pixel-accessor.h" 59#include "MagickCore/property.h" 60#include "MagickCore/quantize.h" 61#include "MagickCore/quantum-private.h" 62#include "MagickCore/static.h" 63#include "MagickCore/string_.h" 64#include "MagickCore/module.h" 65#include "MagickCore/utility.h" 66 67/* 68 Forward declarations. 69*/ 70static MagickBooleanType 71 WriteCIPImage(const ImageInfo *,Image *,ExceptionInfo *); 72 73/* 74%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 75% % 76% % 77% % 78% R e g i s t e r C I P I m a g e % 79% % 80% % 81% % 82%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 83% 84% RegisterCIPImage() adds properties for the CIP IP phone image format to 85% the list of supported formats. The properties include the image format 86% tag, a method to read and/or write the format, whether the format 87% supports the saving of more than one frame to the same file or blob, 88% whether the format supports native in-memory I/O, and a brief 89% description of the format. 90% 91% The format of the RegisterCIPImage method is: 92% 93% size_t RegisterCIPImage(void) 94% 95*/ 96ModuleExport size_t RegisterCIPImage(void) 97{ 98 MagickInfo 99 *entry; 100 101 entry=AcquireMagickInfo("CIP","CIP","Cisco IP phone image format"); 102 entry->encoder=(EncodeImageHandler *) WriteCIPImage; 103 entry->flags^=CoderAdjoinFlag; 104 (void) RegisterMagickInfo(entry); 105 return(MagickImageCoderSignature); 106} 107 108/* 109%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 110% % 111% % 112% % 113% U n r e g i s t e r C I P I m a g e % 114% % 115% % 116% % 117%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 118% 119% UnregisterCIPImage() removes format registrations made by the 120% CIP module from the list of supported formats. 121% 122% The format of the UnregisterCIPImage method is: 123% 124% UnregisterCIPImage(void) 125% 126*/ 127ModuleExport void UnregisterCIPImage(void) 128{ 129 (void) UnregisterMagickInfo("CIP"); 130} 131 132/* 133%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 134% % 135% % 136% % 137% W r i t e C I P I m a g e % 138% % 139% % 140% % 141%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 142% 143% Procedure WriteCIPImage() writes an image to a file in the Cisco IP phone 144% image format. 145% 146% The format of the WriteCIPImage method is: 147% 148% MagickBooleanType WriteCIPImage(const ImageInfo *image_info, 149% Image *image,ExceptionInfo *exception) 150% 151% A description of each parameter follows. 152% 153% o image_info: the image info. 154% 155% o image: The image. 156% 157% o exception: return any errors or warnings in this structure. 158% 159*/ 160static MagickBooleanType WriteCIPImage(const ImageInfo *image_info,Image *image, 161 ExceptionInfo *exception) 162{ 163 char 164 buffer[MagickPathExtent]; 165 166 const char 167 *value; 168 169 MagickBooleanType 170 status; 171 172 register const Quantum 173 *p; 174 175 register ssize_t 176 i, 177 x; 178 179 ssize_t 180 y; 181 182 unsigned char 183 byte; 184 185 /* 186 Open output image file. 187 */ 188 assert(image_info != (const ImageInfo *) NULL); 189 assert(image_info->signature == MagickCoreSignature); 190 assert(image != (Image *) NULL); 191 assert(image->signature == MagickCoreSignature); 192 if (image->debug != MagickFalse) 193 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 194 assert(exception != (ExceptionInfo *) NULL); 195 assert(exception->signature == MagickCoreSignature); 196 status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception); 197 if (status == MagickFalse) 198 return(status); 199 (void) WriteBlobString(image,"<CiscoIPPhoneImage>\n"); 200 value=GetImageProperty(image,"label",exception); 201 if (value != (const char *) NULL) 202 (void) FormatLocaleString(buffer,MagickPathExtent,"<Title>%s</Title>\n",value); 203 else 204 { 205 char 206 basename[MagickPathExtent]; 207 208 GetPathComponent(image->filename,BasePath,basename); 209 (void) FormatLocaleString(buffer,MagickPathExtent,"<Title>%s</Title>\n", 210 basename); 211 } 212 (void) WriteBlobString(image,buffer); 213 (void) FormatLocaleString(buffer,MagickPathExtent, 214 "<LocationX>%.20g</LocationX>\n",(double) image->page.x); 215 (void) WriteBlobString(image,buffer); 216 (void) FormatLocaleString(buffer,MagickPathExtent, 217 "<LocationY>%.20g</LocationY>\n",(double) image->page.y); 218 (void) WriteBlobString(image,buffer); 219 (void) FormatLocaleString(buffer,MagickPathExtent,"<Width>%.20g</Width>\n", 220 (double) (image->columns+(image->columns % 2))); 221 (void) WriteBlobString(image,buffer); 222 (void) FormatLocaleString(buffer,MagickPathExtent,"<Height>%.20g</Height>\n", 223 (double) image->rows); 224 (void) WriteBlobString(image,buffer); 225 (void) FormatLocaleString(buffer,MagickPathExtent,"<Depth>2</Depth>\n"); 226 (void) WriteBlobString(image,buffer); 227 (void) WriteBlobString(image,"<Data>"); 228 (void) TransformImageColorspace(image,sRGBColorspace,exception); 229 for (y=0; y < (ssize_t) image->rows; y++) 230 { 231 p=GetVirtualPixels(image,0,y,image->columns,1,exception); 232 if (p == (const Quantum *) NULL) 233 break; 234 for (x=0; x < ((ssize_t) image->columns-3); x+=4) 235 { 236 byte=(unsigned char) 237 ((((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+3))/QuantumRange) & 0x03) << 6) | 238 (((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+2))/QuantumRange) & 0x03) << 4) | 239 (((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+1))/QuantumRange) & 0x03) << 2) | 240 (((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+0))/QuantumRange) & 0x03) << 0)); 241 (void) FormatLocaleString(buffer,MagickPathExtent,"%02x",byte); 242 (void) WriteBlobString(image,buffer); 243 p+=4; 244 } 245 if ((image->columns % 4) != 0) 246 { 247 i=(ssize_t) image->columns % 4; 248 byte=(unsigned char) 249 ((((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+MagickMin(i,3)))/QuantumRange) & 0x03) << 6) | 250 (((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+MagickMin(i,2)))/QuantumRange) & 0x03) << 4) | 251 (((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+MagickMin(i,1)))/QuantumRange) & 0x03) << 2) | 252 (((size_t) (3*ClampToQuantum(GetPixelLuma(image,p+MagickMin(i,0)))/QuantumRange) & 0x03) << 0)); 253 (void) FormatLocaleString(buffer,MagickPathExtent,"%02x",~byte); 254 (void) WriteBlobString(image,buffer); 255 } 256 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, 257 image->rows); 258 if (status == MagickFalse) 259 break; 260 } 261 (void) WriteBlobString(image,"</Data>\n"); 262 (void) WriteBlobString(image,"</CiscoIPPhoneImage>\n"); 263 (void) CloseBlob(image); 264 return(MagickTrue); 265} 266