MagickCore  6.7.5
signature.c
Go to the documentation of this file.
00001 /*
00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00003 %                                                                             %
00004 %                                                                             %
00005 %        SSSSS  IIIII   GGGG  N   N   AAA   TTTTT  U   U  RRRR   EEEEE        %
00006 %        SS       I    G      NN  N  A   A    T    U   U  R   R  E            %
00007 %         SSS     I    G  GG  N N N  AAAAA    T    U   U  RRRR   EEE          %
00008 %           SS    I    G   G  N  NN  A   A    T    U   U  R R    E            %
00009 %        SSSSS  IIIII   GGG   N   N  A   A    T     UUU   R  R   EEEEE        %
00010 %                                                                             %
00011 %                                                                             %
00012 %         MagickCore Methods to Compute a Message Digest for an Image         %
00013 %                                                                             %
00014 %                             Software Design                                 %
00015 %                               John Cristy                                   %
00016 %                              December 1992                                  %
00017 %                                                                             %
00018 %                                                                             %
00019 %  Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization      %
00020 %  dedicated to making software imaging solutions freely available.           %
00021 %                                                                             %
00022 %  You may not use this file except in compliance with the License.  You may  %
00023 %  obtain a copy of the License at                                            %
00024 %                                                                             %
00025 %    http://www.imagemagick.org/script/license.php                            %
00026 %                                                                             %
00027 %  Unless required by applicable law or agreed to in writing, software        %
00028 %  distributed under the License is distributed on an "AS IS" BASIS,          %
00029 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
00030 %  See the License for the specific language governing permissions and        %
00031 %  limitations under the License.                                             %
00032 %                                                                             %
00033 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00034 %
00035 %
00036 %
00037 */
00038 
00039 /*
00040   Include declarations.
00041 */
00042 #include "MagickCore/studio.h"
00043 #include "MagickCore/cache.h"
00044 #include "MagickCore/exception.h"
00045 #include "MagickCore/exception-private.h"
00046 #include "MagickCore/property.h"
00047 #include "MagickCore/image.h"
00048 #include "MagickCore/memory_.h"
00049 #include "MagickCore/pixel-accessor.h"
00050 #include "MagickCore/quantum.h"
00051 #include "MagickCore/quantum-private.h"
00052 #include "MagickCore/signature.h"
00053 #include "MagickCore/signature-private.h"
00054 #include "MagickCore/string_.h"
00055 /*
00056   Define declarations.
00057 */
00058 #define SignatureBlocksize  64
00059 #define SignatureDigestsize  32
00060 
00061 /*
00062   Typedef declarations.
00063 */
00064 struct _SignatureInfo
00065 {
00066   unsigned int
00067     digestsize,
00068     blocksize;
00069 
00070   StringInfo
00071     *digest,
00072     *message;
00073 
00074   unsigned int
00075     *accumulator,
00076     low_order,
00077     high_order;
00078 
00079   size_t
00080     offset;
00081 
00082   MagickBooleanType
00083     lsb_first;
00084 
00085   ssize_t
00086     timestamp;
00087 
00088   size_t
00089     signature;
00090 };
00091 
00092 /*
00093   Forward declarations.
00094 */
00095 static void
00096   TransformSignature(SignatureInfo *);
00097 
00098 /*
00099 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00100 %                                                                             %
00101 %                                                                             %
00102 %                                                                             %
00103 +   A c q u i r e S i g n a t u r e I n f o                                   %
00104 %                                                                             %
00105 %                                                                             %
00106 %                                                                             %
00107 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00108 %
00109 %  AcquireSignatureInfo() allocate the SignatureInfo structure.
00110 %
00111 %  The format of the AcquireSignatureInfo method is:
00112 %
00113 %      SignatureInfo *AcquireSignatureInfo(void)
00114 %
00115 */
00116 MagickPrivate SignatureInfo *AcquireSignatureInfo(void)
00117 {
00118   SignatureInfo
00119     *signature_info;
00120 
00121   unsigned int
00122     lsb_first;
00123 
00124   signature_info=(SignatureInfo *) AcquireMagickMemory(sizeof(*signature_info));
00125   if (signature_info == (SignatureInfo *) NULL)
00126     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
00127   (void) ResetMagickMemory(signature_info,0,sizeof(*signature_info));
00128   signature_info->digestsize=SignatureDigestsize;
00129   signature_info->blocksize=SignatureBlocksize;
00130   signature_info->digest=AcquireStringInfo(SignatureDigestsize);
00131   signature_info->message=AcquireStringInfo(SignatureBlocksize);
00132   signature_info->accumulator=(unsigned int *) AcquireQuantumMemory(
00133     SignatureBlocksize,sizeof(*signature_info->accumulator));
00134   if (signature_info->accumulator == (unsigned int *) NULL)
00135     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
00136   lsb_first=1;
00137   signature_info->lsb_first=(int) (*(char *) &lsb_first) == 1 ? MagickTrue :
00138     MagickFalse;
00139   signature_info->timestamp=(ssize_t) time(0);
00140   signature_info->signature=MagickSignature;
00141   InitializeSignature(signature_info);
00142   return(signature_info);
00143 }
00144 
00145 /*
00146 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00147 %                                                                             %
00148 %                                                                             %
00149 %                                                                             %
00150 +   D e s t r o y S i g n a t u r e I n f o                                   %
00151 %                                                                             %
00152 %                                                                             %
00153 %                                                                             %
00154 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00155 %
00156 %  DestroySignatureInfo() zeros memory associated with the SignatureInfo
00157 %  structure.
00158 %
00159 %  The format of the DestroySignatureInfo method is:
00160 %
00161 %      SignatureInfo *DestroySignatureInfo(SignatureInfo *signature_info)
00162 %
00163 %  A description of each parameter follows:
00164 %
00165 %    o signature_info: the cipher signature_info.
00166 %
00167 */
00168 MagickPrivate SignatureInfo *DestroySignatureInfo(SignatureInfo *signature_info)
00169 {
00170   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00171   assert(signature_info != (SignatureInfo *) NULL);
00172   assert(signature_info->signature == MagickSignature);
00173   if (signature_info->accumulator != (unsigned int *) NULL)
00174     signature_info->accumulator=(unsigned int *) RelinquishMagickMemory(
00175       signature_info->accumulator);
00176   if (signature_info->message != (StringInfo *) NULL)
00177     signature_info->message=DestroyStringInfo(signature_info->message);
00178   if (signature_info->digest != (StringInfo *) NULL)
00179     signature_info->digest=DestroyStringInfo(signature_info->digest);
00180   signature_info->signature=(~MagickSignature);
00181   signature_info=(SignatureInfo *) RelinquishMagickMemory(signature_info);
00182   return(signature_info);
00183 }
00184 
00185 /*
00186 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00187 %                                                                             %
00188 %                                                                             %
00189 %                                                                             %
00190 +   F i n a l i z e S i g n a t u r e                                         %
00191 %                                                                             %
00192 %                                                                             %
00193 %                                                                             %
00194 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00195 %
00196 %  FinalizeSignature() finalizes the Signature message accumulator computation.
00197 %
00198 %  The format of the FinalizeSignature method is:
00199 %
00200 %      FinalizeSignature(SignatureInfo *signature_info)
00201 %
00202 %  A description of each parameter follows:
00203 %
00204 %    o signature_info: the address of a structure of type SignatureInfo.
00205 %
00206 */
00207 MagickPrivate void FinalizeSignature(SignatureInfo *signature_info)
00208 {
00209   register ssize_t
00210     i;
00211 
00212   register unsigned char
00213     *q;
00214 
00215   register unsigned int
00216     *p;
00217 
00218   unsigned char
00219     *datum;
00220 
00221   unsigned int
00222     count,
00223     high_order,
00224     low_order;
00225 
00226   /*
00227     Add padding and return the message accumulator.
00228   */
00229   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00230   assert(signature_info != (SignatureInfo *) NULL);
00231   assert(signature_info->signature == MagickSignature);
00232   low_order=signature_info->low_order;
00233   high_order=signature_info->high_order;
00234   count=((low_order >> 3) & 0x3f);
00235   datum=GetStringInfoDatum(signature_info->message);
00236   datum[count++]=(unsigned char) 0x80;
00237   if (count <= (unsigned int) (GetStringInfoLength(signature_info->message)-8))
00238     (void) ResetMagickMemory(datum+count,0,GetStringInfoLength(
00239       signature_info->message)-8-count);
00240   else
00241     {
00242       (void) ResetMagickMemory(datum+count,0,GetStringInfoLength(
00243         signature_info->message)-count);
00244       TransformSignature(signature_info);
00245       (void) ResetMagickMemory(datum,0,GetStringInfoLength(
00246         signature_info->message)-8);
00247     }
00248   datum[56]=(unsigned char) (high_order >> 24);
00249   datum[57]=(unsigned char) (high_order >> 16);
00250   datum[58]=(unsigned char) (high_order >> 8);
00251   datum[59]=(unsigned char) high_order;
00252   datum[60]=(unsigned char) (low_order >> 24);
00253   datum[61]=(unsigned char) (low_order >> 16);
00254   datum[62]=(unsigned char) (low_order >> 8);
00255   datum[63]=(unsigned char) low_order;
00256   TransformSignature(signature_info);
00257   p=signature_info->accumulator;
00258   q=GetStringInfoDatum(signature_info->digest);
00259   for (i=0; i < (SignatureDigestsize/4); i++)
00260   {
00261     *q++=(unsigned char) ((*p >> 24) & 0xff);
00262     *q++=(unsigned char) ((*p >> 16) & 0xff);
00263     *q++=(unsigned char) ((*p >> 8) & 0xff);
00264     *q++=(unsigned char) (*p & 0xff);
00265     p++;
00266   }
00267   /*
00268     Reset working registers.
00269   */
00270   count=0;
00271   high_order=0;
00272   low_order=0;
00273 }
00274 
00275 /*
00276 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00277 %                                                                             %
00278 %                                                                             %
00279 %                                                                             %
00280 +   G e t S i g n a t u r e B l o c k s i z e                                 %
00281 %                                                                             %
00282 %                                                                             %
00283 %                                                                             %
00284 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00285 %
00286 %  GetSignatureBlocksize() returns the Signature blocksize.
00287 %
00288 %  The format of the GetSignatureBlocksize method is:
00289 %
00290 %      unsigned int *GetSignatureBlocksize(const SignatureInfo *signature_info)
00291 %
00292 %  A description of each parameter follows:
00293 %
00294 %    o signature_info: the signature info.
00295 %
00296 */
00297 MagickPrivate unsigned int GetSignatureBlocksize(
00298   const SignatureInfo *signature_info)
00299 {
00300   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00301   assert(signature_info != (SignatureInfo *) NULL);
00302   assert(signature_info->signature == MagickSignature);
00303   return(signature_info->blocksize);
00304 }
00305 
00306 /*
00307 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00308 %                                                                             %
00309 %                                                                             %
00310 %                                                                             %
00311 +   G e t S i g n a t u r e D i g e s t                                       %
00312 %                                                                             %
00313 %                                                                             %
00314 %                                                                             %
00315 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00316 %
00317 %  GetSignatureDigest() returns the signature digest.
00318 %
00319 %  The format of the GetSignatureDigest method is:
00320 %
00321 %      const StringInfo *GetSignatureDigest(const SignatureInfo *signature_info)
00322 %
00323 %  A description of each parameter follows:
00324 %
00325 %    o signature_info: the signature info.
00326 %
00327 */
00328 MagickPrivate const StringInfo *GetSignatureDigest(
00329   const SignatureInfo *signature_info)
00330 {
00331   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00332   assert(signature_info != (SignatureInfo *) NULL);
00333   assert(signature_info->signature == MagickSignature);
00334   return(signature_info->digest);
00335 }
00336 
00337 /*
00338 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00339 %                                                                             %
00340 %                                                                             %
00341 %                                                                             %
00342 +   G e t S i g n a t u r e D i g e s t s i z e                               %
00343 %                                                                             %
00344 %                                                                             %
00345 %                                                                             %
00346 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00347 %
00348 %  GetSignatureDigestsize() returns the Signature digest size.
00349 %
00350 %  The format of the GetSignatureDigestsize method is:
00351 %
00352 %      unsigned int *GetSignatureDigestsize(const SignatureInfo *signature_info)
00353 %
00354 %  A description of each parameter follows:
00355 %
00356 %    o signature_info: the signature info.
00357 %
00358 */
00359 MagickPrivate unsigned int GetSignatureDigestsize(
00360   const SignatureInfo *signature_info)
00361 {
00362   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00363   assert(signature_info != (SignatureInfo *) NULL);
00364   assert(signature_info->signature == MagickSignature);
00365   return(signature_info->digestsize);
00366 }
00367 
00368 /*
00369 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00370 %                                                                             %
00371 %                                                                             %
00372 %                                                                             %
00373 +   I n i t i a l i z e S i g n a t u r e                                     %
00374 %                                                                             %
00375 %                                                                             %
00376 %                                                                             %
00377 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00378 %
00379 %  InitializeSignature() initializes the Signature accumulator.
00380 %
00381 %  The format of the DestroySignatureInfo method is:
00382 %
00383 %      void InitializeSignatureInfo(SignatureInfo *signature_info)
00384 %
00385 %  A description of each parameter follows:
00386 %
00387 %    o signature_info: the cipher signature_info.
00388 %
00389 */
00390 MagickPrivate void InitializeSignature(SignatureInfo *signature_info)
00391 {
00392   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00393   assert(signature_info != (SignatureInfo *) NULL);
00394   assert(signature_info->signature == MagickSignature);
00395   signature_info->accumulator[0]=0x6a09e667U;
00396   signature_info->accumulator[1]=0xbb67ae85U;
00397   signature_info->accumulator[2]=0x3c6ef372U;
00398   signature_info->accumulator[3]=0xa54ff53aU;
00399   signature_info->accumulator[4]=0x510e527fU;
00400   signature_info->accumulator[5]=0x9b05688cU;
00401   signature_info->accumulator[6]=0x1f83d9abU;
00402   signature_info->accumulator[7]=0x5be0cd19U;
00403   signature_info->low_order=0;
00404   signature_info->high_order=0;
00405   signature_info->offset=0;
00406 }
00407 
00408 /*
00409 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00410 %                                                                             %
00411 %                                                                             %
00412 %                                                                             %
00413 +   S e t S i g n a t u r e D i g e s t                                       %
00414 %                                                                             %
00415 %                                                                             %
00416 %                                                                             %
00417 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00418 %
00419 %  SetSignatureDigest() set the signature digest.
00420 %
00421 %  The format of the SetSignatureDigest method is:
00422 %
00423 %      SetSignatureDigest(SignatureInfo *signature_info,
00424 %        const StringInfo *digest)
00425 %
00426 %  A description of each parameter follows:
00427 %
00428 %    o signature_info: the signature info.
00429 %
00430 %    o digest: the digest.
00431 %
00432 */
00433 MagickPrivate void SetSignatureDigest(SignatureInfo *signature_info,
00434   const StringInfo *digest)
00435 {
00436   /*
00437     Set the signature accumulator.
00438   */
00439   assert(signature_info != (SignatureInfo *) NULL);
00440   assert(signature_info->signature == MagickSignature);
00441   SetStringInfo(signature_info->digest,digest);
00442 }
00443 
00444 /*
00445 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00446 %                                                                             %
00447 %                                                                             %
00448 %                                                                             %
00449 %   S i g n a t u r e I m a g e                                               %
00450 %                                                                             %
00451 %                                                                             %
00452 %                                                                             %
00453 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00454 %
00455 %  SignatureImage() computes a message digest from an image pixel stream with
00456 %  an implementation of the NIST SHA-256 Message Digest algorithm.  This
00457 %  signature uniquely identifies the image and is convenient for determining
00458 %  if an image has been modified or whether two images are identical.
00459 %
00460 %  The format of the SignatureImage method is:
00461 %
00462 %      MagickBooleanType SignatureImage(Image *image,ExceptionInfo *exception)
00463 %
00464 %  A description of each parameter follows:
00465 %
00466 %    o image: the image.
00467 %
00468 %    o exception: return any errors or warnings in this structure.
00469 %
00470 */
00471 MagickExport MagickBooleanType SignatureImage(Image *image,
00472   ExceptionInfo *exception)
00473 {
00474   CacheView
00475     *image_view;
00476 
00477   char
00478     *hex_signature;
00479 
00480   double
00481     pixel;
00482 
00483   register const Quantum
00484     *p;
00485 
00486   SignatureInfo
00487     *signature_info;
00488 
00489   ssize_t
00490     y;
00491 
00492   StringInfo
00493     *signature;
00494 
00495   unsigned char
00496     *pixels;
00497 
00498   /*
00499     Compute image digital signature.
00500   */
00501   assert(image != (Image *) NULL);
00502   assert(image->signature == MagickSignature);
00503   if (image->debug != MagickFalse)
00504     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00505   signature_info=AcquireSignatureInfo();
00506   signature=AcquireStringInfo(image->columns*GetPixelChannels(image)*
00507     sizeof(pixel));
00508   pixels=GetStringInfoDatum(signature);
00509   image_view=AcquireCacheView(image);
00510   for (y=0; y < (ssize_t) image->rows; y++)
00511   {
00512     register ssize_t
00513       x;
00514 
00515     register unsigned char
00516       *q;
00517 
00518     p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
00519     if (p == (const Quantum *) NULL)
00520       break;
00521     q=pixels;
00522     for (x=0; x < (ssize_t) image->columns; x++)
00523     {
00524       register ssize_t
00525         i;
00526 
00527       if (GetPixelMask(image,p) != 0)
00528         {
00529           p+=GetPixelChannels(image);
00530           continue;
00531         }
00532       for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
00533       {
00534         PixelChannel
00535           channel;
00536 
00537         PixelTrait
00538           traits;
00539 
00540         register ssize_t
00541           j;
00542 
00543         channel=GetPixelChannelMapChannel(image,i);
00544         traits=GetPixelChannelMapTraits(image,channel);
00545         if (traits == UndefinedPixelTrait)
00546           continue;
00547         pixel=QuantumScale*p[i];
00548         for (j=0; j < (ssize_t) sizeof(pixel); j++)
00549           *q++=(unsigned char) (&pixel)[j];
00550       }
00551       p+=GetPixelChannels(image);
00552     }
00553     SetStringInfoLength(signature,(size_t) (q-pixels));
00554     UpdateSignature(signature_info,signature);
00555   }
00556   image_view=DestroyCacheView(image_view);
00557   FinalizeSignature(signature_info);
00558   hex_signature=StringInfoToHexString(GetSignatureDigest(signature_info));
00559   (void) DeleteImageProperty(image,"signature");
00560   (void) SetImageProperty(image,"signature",hex_signature,exception);
00561   /*
00562     Free resources.
00563   */
00564   hex_signature=DestroyString(hex_signature);
00565   signature=DestroyStringInfo(signature);
00566   signature_info=DestroySignatureInfo(signature_info);
00567   return(MagickTrue);
00568 }
00569 
00570 /*
00571 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00572 %                                                                             %
00573 %                                                                             %
00574 %                                                                             %
00575 +   T r a n s f o r m S i g n a t u r e                                       %
00576 %                                                                             %
00577 %                                                                             %
00578 %                                                                             %
00579 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00580 %
00581 %  TransformSignature() transforms the Signature message accumulator.
00582 %
00583 %  The format of the TransformSignature method is:
00584 %
00585 %      TransformSignature(SignatureInfo *signature_info)
00586 %
00587 %  A description of each parameter follows:
00588 %
00589 %    o signature_info: the address of a structure of type SignatureInfo.
00590 %
00591 */
00592 
00593 static inline unsigned int Ch(unsigned int x,unsigned int y,unsigned int z)
00594 {
00595   return((x & y) ^ (~x & z));
00596 }
00597 
00598 static inline unsigned int Maj(unsigned int x,unsigned int y,unsigned int z)
00599 {
00600   return((x & y) ^ (x & z) ^ (y & z));
00601 }
00602 
00603 static inline unsigned int Trunc32(unsigned int x)
00604 {
00605   return((unsigned int) (x & 0xffffffffU));
00606 }
00607 
00608 static unsigned int RotateRight(unsigned int x,unsigned int n)
00609 {
00610   return(Trunc32((x >> n) | (x << (32-n))));
00611 }
00612 
00613 static void TransformSignature(SignatureInfo *signature_info)
00614 {
00615 #define Sigma0(x)  (RotateRight(x,7) ^ RotateRight(x,18) ^ Trunc32((x) >> 3))
00616 #define Sigma1(x)  (RotateRight(x,17) ^ RotateRight(x,19) ^ Trunc32((x) >> 10))
00617 #define Suma0(x)  (RotateRight(x,2) ^ RotateRight(x,13) ^ RotateRight(x,22))
00618 #define Suma1(x)  (RotateRight(x,6) ^ RotateRight(x,11) ^ RotateRight(x,25))
00619 
00620   register ssize_t
00621     i;
00622 
00623   register unsigned char
00624     *p;
00625 
00626   ssize_t
00627     j;
00628 
00629   static unsigned int
00630     K[64] =
00631     {
00632       0x428a2f98U, 0x71374491U, 0xb5c0fbcfU, 0xe9b5dba5U, 0x3956c25bU,
00633       0x59f111f1U, 0x923f82a4U, 0xab1c5ed5U, 0xd807aa98U, 0x12835b01U,
00634       0x243185beU, 0x550c7dc3U, 0x72be5d74U, 0x80deb1feU, 0x9bdc06a7U,
00635       0xc19bf174U, 0xe49b69c1U, 0xefbe4786U, 0x0fc19dc6U, 0x240ca1ccU,
00636       0x2de92c6fU, 0x4a7484aaU, 0x5cb0a9dcU, 0x76f988daU, 0x983e5152U,
00637       0xa831c66dU, 0xb00327c8U, 0xbf597fc7U, 0xc6e00bf3U, 0xd5a79147U,
00638       0x06ca6351U, 0x14292967U, 0x27b70a85U, 0x2e1b2138U, 0x4d2c6dfcU,
00639       0x53380d13U, 0x650a7354U, 0x766a0abbU, 0x81c2c92eU, 0x92722c85U,
00640       0xa2bfe8a1U, 0xa81a664bU, 0xc24b8b70U, 0xc76c51a3U, 0xd192e819U,
00641       0xd6990624U, 0xf40e3585U, 0x106aa070U, 0x19a4c116U, 0x1e376c08U,
00642       0x2748774cU, 0x34b0bcb5U, 0x391c0cb3U, 0x4ed8aa4aU, 0x5b9cca4fU,
00643       0x682e6ff3U, 0x748f82eeU, 0x78a5636fU, 0x84c87814U, 0x8cc70208U,
00644       0x90befffaU, 0xa4506cebU, 0xbef9a3f7U, 0xc67178f2U
00645     };  /* 32-bit fractional part of the cube root of the first 64 primes */
00646 
00647   unsigned int
00648     A,
00649     B,
00650     C,
00651     D,
00652     E,
00653     F,
00654     G,
00655     H,
00656     shift,
00657     T,
00658     T1,
00659     T2,
00660     W[64];
00661 
00662   shift=32;
00663   p=GetStringInfoDatum(signature_info->message);
00664   if (signature_info->lsb_first == MagickFalse)
00665     {
00666       if (sizeof(unsigned int) <= 4)
00667         for (i=0; i < 16; i++)
00668         {
00669           T=(*((unsigned int *) p));
00670           p+=4;
00671           W[i]=Trunc32(T);
00672         }
00673       else
00674         for (i=0; i < 16; i+=2)
00675         {
00676           T=(*((unsigned int *) p));
00677           p+=8;
00678           W[i]=Trunc32(T >> shift);
00679           W[i+1]=Trunc32(T);
00680         }
00681     }
00682   else
00683     if (sizeof(unsigned int) <= 4)
00684       for (i=0; i < 16; i++)
00685       {
00686         T=(*((unsigned int *) p));
00687         p+=4;
00688         W[i]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
00689           ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
00690       }
00691     else
00692       for (i=0; i < 16; i+=2)
00693       {
00694         T=(*((unsigned int *) p));
00695         p+=8;
00696         W[i]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
00697           ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
00698         T>>=shift;
00699         W[i+1]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
00700           ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
00701       }
00702   /*
00703     Copy accumulator to registers.
00704   */
00705   A=signature_info->accumulator[0];
00706   B=signature_info->accumulator[1];
00707   C=signature_info->accumulator[2];
00708   D=signature_info->accumulator[3];
00709   E=signature_info->accumulator[4];
00710   F=signature_info->accumulator[5];
00711   G=signature_info->accumulator[6];
00712   H=signature_info->accumulator[7];
00713   for (i=16; i < 64; i++)
00714     W[i]=Trunc32(Sigma1(W[i-2])+W[i-7]+Sigma0(W[i-15])+W[i-16]);
00715   for (j=0; j < 64; j++)
00716   {
00717     T1=Trunc32(H+Suma1(E)+Ch(E,F,G)+K[j]+W[j]);
00718     T2=Trunc32(Suma0(A)+Maj(A,B,C));
00719     H=G;
00720     G=F;
00721     F=E;
00722     E=Trunc32(D+T1);
00723     D=C;
00724     C=B;
00725     B=A;
00726     A=Trunc32(T1+T2);
00727   }
00728   /*
00729     Add registers back to accumulator.
00730   */
00731   signature_info->accumulator[0]=Trunc32(signature_info->accumulator[0]+A);
00732   signature_info->accumulator[1]=Trunc32(signature_info->accumulator[1]+B);
00733   signature_info->accumulator[2]=Trunc32(signature_info->accumulator[2]+C);
00734   signature_info->accumulator[3]=Trunc32(signature_info->accumulator[3]+D);
00735   signature_info->accumulator[4]=Trunc32(signature_info->accumulator[4]+E);
00736   signature_info->accumulator[5]=Trunc32(signature_info->accumulator[5]+F);
00737   signature_info->accumulator[6]=Trunc32(signature_info->accumulator[6]+G);
00738   signature_info->accumulator[7]=Trunc32(signature_info->accumulator[7]+H);
00739   /*
00740     Reset working registers.
00741   */
00742   A=0;
00743   B=0;
00744   C=0;
00745   D=0;
00746   E=0;
00747   F=0;
00748   G=0;
00749   H=0;
00750   T=0;
00751   T1=0;
00752   T2=0;
00753   (void) ResetMagickMemory(W,0,sizeof(W));
00754 }
00755 
00756 /*
00757 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00758 %                                                                             %
00759 %                                                                             %
00760 %                                                                             %
00761 +   U p d a t e S i g n a t u r e                                             %
00762 %                                                                             %
00763 %                                                                             %
00764 %                                                                             %
00765 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00766 %
00767 %  UpdateSignature() updates the Signature message accumulator.
00768 %
00769 %  The format of the UpdateSignature method is:
00770 %
00771 %      UpdateSignature(SignatureInfo *signature_info,const StringInfo *message)
00772 %
00773 %  A description of each parameter follows:
00774 %
00775 %    o signature_info: the address of a structure of type SignatureInfo.
00776 %
00777 %    o message: the message.
00778 %
00779 */
00780 MagickPrivate void UpdateSignature(SignatureInfo *signature_info,
00781   const StringInfo *message)
00782 {
00783   register size_t
00784     i;
00785 
00786   register unsigned char
00787     *p;
00788 
00789   size_t
00790     n;
00791 
00792   unsigned int
00793     length;
00794 
00795   /*
00796     Update the Signature accumulator.
00797   */
00798   assert(signature_info != (SignatureInfo *) NULL);
00799   assert(signature_info->signature == MagickSignature);
00800   n=GetStringInfoLength(message);
00801   length=Trunc32((unsigned int) (signature_info->low_order+(n << 3)));
00802   if (length < signature_info->low_order)
00803     signature_info->high_order++;
00804   signature_info->low_order=length;
00805   signature_info->high_order+=(unsigned int) (n >> 29);
00806   p=GetStringInfoDatum(message);
00807   if (signature_info->offset != 0)
00808     {
00809       i=GetStringInfoLength(signature_info->message)-signature_info->offset;
00810       if (i > n)
00811         i=n;
00812       (void) CopyMagickMemory(GetStringInfoDatum(signature_info->message)+
00813         signature_info->offset,p,i);
00814       n-=i;
00815       p+=i;
00816       signature_info->offset+=i;
00817       if (signature_info->offset !=
00818           GetStringInfoLength(signature_info->message))
00819         return;
00820       TransformSignature(signature_info);
00821     }
00822   while (n >= GetStringInfoLength(signature_info->message))
00823   {
00824     SetStringInfoDatum(signature_info->message,p);
00825     p+=GetStringInfoLength(signature_info->message);
00826     n-=GetStringInfoLength(signature_info->message);
00827     TransformSignature(signature_info);
00828   }
00829   (void) CopyMagickMemory(GetStringInfoDatum(signature_info->message),p,n);
00830   signature_info->offset=n;
00831   /*
00832     Reset working registers.
00833   */
00834   i=0;
00835   n=0;
00836   length=0;
00837 }