MagickCore 7.1.1
Convert, Edit, Or Compose Bitmap Images
Loading...
Searching...
No Matches
signature.c
1/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% SSSSS IIIII GGGG N N AAA TTTTT U U RRRR EEEEE %
6% SS I G NN N A A T U U R R E %
7% SSS I G GG N N N AAAAA T U U RRRR EEE %
8% SS I G G N NN A A T U U R R E %
9% SSSSS IIIII GGG N N A A T UUU R R EEEEE %
10% %
11% %
12% MagickCore Methods to Compute a Message Digest for an Image %
13% %
14% Software Design %
15% Cristy %
16% December 1992 %
17% %
18% %
19% Copyright @ 1999 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% https://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/*
40 Include declarations.
41*/
42#include "MagickCore/studio.h"
43#include "MagickCore/cache.h"
44#include "MagickCore/exception.h"
45#include "MagickCore/exception-private.h"
46#include "MagickCore/property.h"
47#include "MagickCore/image.h"
48#include "MagickCore/memory_.h"
49#include "MagickCore/memory-private.h"
50#include "MagickCore/pixel-accessor.h"
51#include "MagickCore/quantum.h"
52#include "MagickCore/quantum-private.h"
53#include "MagickCore/signature.h"
54#include "MagickCore/signature-private.h"
55#include "MagickCore/string_.h"
56#include "MagickCore/timer-private.h"
57/*
58 Define declarations.
59*/
60#define SignatureBlocksize 64
61#define SignatureDigestsize 32
62
63/*
64 Typedef declarations.
65*/
67{
68 unsigned int
69 digestsize,
70 blocksize;
71
73 *digest,
74 *message;
75
76 unsigned int
77 *accumulator,
78 low_order,
79 high_order;
80
81 size_t
82 extent;
83
84 MagickBooleanType
85 lsb_first;
86
87 time_t
88 timestamp;
89
90 size_t
91 signature;
92};
93
94/*
95 Forward declarations.
96*/
97static void
98 TransformSignature(SignatureInfo *);
99
100/*
101%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
102% %
103% %
104% %
105+ A c q u i r e S i g n a t u r e I n f o %
106% %
107% %
108% %
109%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
110%
111% AcquireSignatureInfo() allocate the SignatureInfo structure.
112%
113% The format of the AcquireSignatureInfo method is:
114%
115% SignatureInfo *AcquireSignatureInfo(void)
116%
117*/
118MagickPrivate SignatureInfo *AcquireSignatureInfo(void)
119{
121 *signature_info;
122
123 unsigned long
124 lsb_first;
125
126 signature_info=(SignatureInfo *) AcquireCriticalMemory(
127 sizeof(*signature_info));
128 (void) memset(signature_info,0,sizeof(*signature_info));
129 signature_info->digestsize=SignatureDigestsize;
130 signature_info->blocksize=SignatureBlocksize;
131 signature_info->digest=AcquireStringInfo(SignatureDigestsize);
132 signature_info->message=AcquireStringInfo(SignatureBlocksize);
133 signature_info->accumulator=(unsigned int *) AcquireQuantumMemory(
134 SignatureBlocksize,sizeof(*signature_info->accumulator));
135 if (signature_info->accumulator == (unsigned int *) NULL)
136 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
137 (void) memset(signature_info->accumulator,0,SignatureBlocksize*
138 sizeof(*signature_info->accumulator));
139 lsb_first=1;
140 signature_info->lsb_first=(int) (*(char *) &lsb_first) == 1 ? MagickTrue :
141 MagickFalse;
142 signature_info->timestamp=GetMagickTime();
143 signature_info->signature=MagickCoreSignature;
144 InitializeSignature(signature_info);
145 return(signature_info);
146}
147
148/*
149%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
150% %
151% %
152% %
153+ D e s t r o y S i g n a t u r e I n f o %
154% %
155% %
156% %
157%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
158%
159% DestroySignatureInfo() zeros memory associated with the SignatureInfo
160% structure.
161%
162% The format of the DestroySignatureInfo method is:
163%
164% SignatureInfo *DestroySignatureInfo(SignatureInfo *signature_info)
165%
166% A description of each parameter follows:
167%
168% o signature_info: the cipher signature_info.
169%
170*/
171MagickPrivate SignatureInfo *DestroySignatureInfo(SignatureInfo *signature_info)
172{
173 assert(signature_info != (SignatureInfo *) NULL);
174 assert(signature_info->signature == MagickCoreSignature);
175 if (IsEventLogging() != MagickFalse)
176 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
177 if (signature_info->accumulator != (unsigned int *) NULL)
178 signature_info->accumulator=(unsigned int *) RelinquishMagickMemory(
179 signature_info->accumulator);
180 if (signature_info->message != (StringInfo *) NULL)
181 signature_info->message=DestroyStringInfo(signature_info->message);
182 if (signature_info->digest != (StringInfo *) NULL)
183 signature_info->digest=DestroyStringInfo(signature_info->digest);
184 signature_info->signature=(~MagickCoreSignature);
185 signature_info=(SignatureInfo *) RelinquishMagickMemory(signature_info);
186 return(signature_info);
187}
188
189/*
190%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
191% %
192% %
193% %
194+ F i n a l i z e S i g n a t u r e %
195% %
196% %
197% %
198%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
199%
200% FinalizeSignature() finalizes the Signature message accumulator computation.
201%
202% The format of the FinalizeSignature method is:
203%
204% FinalizeSignature(SignatureInfo *signature_info)
205%
206% A description of each parameter follows:
207%
208% o signature_info: the address of a structure of type SignatureInfo.
209%
210*/
211MagickPrivate void FinalizeSignature(SignatureInfo *signature_info)
212{
213 ssize_t
214 i;
215
216 unsigned char
217 *q;
218
219 unsigned int
220 *p;
221
222 size_t
223 extent;
224
225 unsigned char
226 *datum;
227
228 unsigned int
229 high_order,
230 low_order;
231
232 /*
233 Add padding and return the message accumulator.
234 */
235 assert(signature_info != (SignatureInfo *) NULL);
236 assert(signature_info->signature == MagickCoreSignature);
237 if (IsEventLogging() != MagickFalse)
238 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
239 low_order=signature_info->low_order;
240 high_order=signature_info->high_order;
241 extent=((low_order >> 3) & 0x3f);
242 datum=GetStringInfoDatum(signature_info->message);
243 datum[extent++]=(unsigned char) 0x80;
244 if (extent <= (unsigned int) (GetStringInfoLength(signature_info->message)-8))
245 (void) memset(datum+extent,0,GetStringInfoLength(
246 signature_info->message)-8-extent);
247 else
248 {
249 (void) memset(datum+extent,0,GetStringInfoLength(
250 signature_info->message)-extent);
251 TransformSignature(signature_info);
252 (void) memset(datum,0,GetStringInfoLength(
253 signature_info->message)-8);
254 }
255 datum[56]=(unsigned char) (high_order >> 24);
256 datum[57]=(unsigned char) (high_order >> 16);
257 datum[58]=(unsigned char) (high_order >> 8);
258 datum[59]=(unsigned char) high_order;
259 datum[60]=(unsigned char) (low_order >> 24);
260 datum[61]=(unsigned char) (low_order >> 16);
261 datum[62]=(unsigned char) (low_order >> 8);
262 datum[63]=(unsigned char) low_order;
263 TransformSignature(signature_info);
264 p=signature_info->accumulator;
265 q=GetStringInfoDatum(signature_info->digest);
266 for (i=0; i < (SignatureDigestsize/4); i++)
267 {
268 *q++=(unsigned char) ((*p >> 24) & 0xff);
269 *q++=(unsigned char) ((*p >> 16) & 0xff);
270 *q++=(unsigned char) ((*p >> 8) & 0xff);
271 *q++=(unsigned char) (*p & 0xff);
272 p++;
273 }
274}
275
276/*
277%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
278% %
279% %
280% %
281+ G e t S i g n a t u r e B l o c k s i z e %
282% %
283% %
284% %
285%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
286%
287% GetSignatureBlocksize() returns the Signature blocksize.
288%
289% The format of the GetSignatureBlocksize method is:
290%
291% unsigned int *GetSignatureBlocksize(const SignatureInfo *signature_info)
292%
293% A description of each parameter follows:
294%
295% o signature_info: the signature info.
296%
297*/
298MagickPrivate unsigned int GetSignatureBlocksize(
299 const SignatureInfo *signature_info)
300{
301 assert(signature_info != (SignatureInfo *) NULL);
302 assert(signature_info->signature == MagickCoreSignature);
303 if (IsEventLogging() != MagickFalse)
304 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
305 return(signature_info->blocksize);
306}
307
308/*
309%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
310% %
311% %
312% %
313+ G e t S i g n a t u r e D i g e s t %
314% %
315% %
316% %
317%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
318%
319% GetSignatureDigest() returns the signature digest.
320%
321% The format of the GetSignatureDigest method is:
322%
323% const StringInfo *GetSignatureDigest(const SignatureInfo *signature_info)
324%
325% A description of each parameter follows:
326%
327% o signature_info: the signature info.
328%
329*/
330MagickPrivate const StringInfo *GetSignatureDigest(
331 const SignatureInfo *signature_info)
332{
333 assert(signature_info != (SignatureInfo *) NULL);
334 assert(signature_info->signature == MagickCoreSignature);
335 if (IsEventLogging() != MagickFalse)
336 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
337 return(signature_info->digest);
338}
339
340/*
341%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
342% %
343% %
344% %
345+ G e t S i g n a t u r e D i g e s t s i z e %
346% %
347% %
348% %
349%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
350%
351% GetSignatureDigestsize() returns the Signature digest size.
352%
353% The format of the GetSignatureDigestsize method is:
354%
355% unsigned int *GetSignatureDigestsize(const SignatureInfo *signature_info)
356%
357% A description of each parameter follows:
358%
359% o signature_info: the signature info.
360%
361*/
362MagickPrivate unsigned int GetSignatureDigestsize(
363 const SignatureInfo *signature_info)
364{
365 assert(signature_info != (SignatureInfo *) NULL);
366 assert(signature_info->signature == MagickCoreSignature);
367 if (IsEventLogging() != MagickFalse)
368 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
369 return(signature_info->digestsize);
370}
371
372/*
373%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
374% %
375% %
376% %
377+ I n i t i a l i z e S i g n a t u r e %
378% %
379% %
380% %
381%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
382%
383% InitializeSignature() initializes the Signature accumulator.
384%
385% The format of the DestroySignatureInfo method is:
386%
387% void InitializeSignatureInfo(SignatureInfo *signature_info)
388%
389% A description of each parameter follows:
390%
391% o signature_info: the cipher signature_info.
392%
393*/
394MagickPrivate void InitializeSignature(SignatureInfo *signature_info)
395{
396 assert(signature_info != (SignatureInfo *) NULL);
397 assert(signature_info->signature == MagickCoreSignature);
398 if (IsEventLogging() != MagickFalse)
399 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
400 signature_info->accumulator[0]=0x6a09e667U;
401 signature_info->accumulator[1]=0xbb67ae85U;
402 signature_info->accumulator[2]=0x3c6ef372U;
403 signature_info->accumulator[3]=0xa54ff53aU;
404 signature_info->accumulator[4]=0x510e527fU;
405 signature_info->accumulator[5]=0x9b05688cU;
406 signature_info->accumulator[6]=0x1f83d9abU;
407 signature_info->accumulator[7]=0x5be0cd19U;
408 signature_info->low_order=0;
409 signature_info->high_order=0;
410 signature_info->extent=0;
411}
412
413/*
414%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
415% %
416% %
417% %
418+ S e t S i g n a t u r e D i g e s t %
419% %
420% %
421% %
422%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
423%
424% SetSignatureDigest() set the signature digest.
425%
426% The format of the SetSignatureDigest method is:
427%
428% SetSignatureDigest(SignatureInfo *signature_info,
429% const StringInfo *digest)
430%
431% A description of each parameter follows:
432%
433% o signature_info: the signature info.
434%
435% o digest: the digest.
436%
437*/
438MagickPrivate void SetSignatureDigest(SignatureInfo *signature_info,
439 const StringInfo *digest)
440{
441 /*
442 Set the signature accumulator.
443 */
444 assert(signature_info != (SignatureInfo *) NULL);
445 assert(signature_info->signature == MagickCoreSignature);
446 SetStringInfo(signature_info->digest,digest);
447}
448
449/*
450%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
451% %
452% %
453% %
454% S i g n a t u r e I m a g e %
455% %
456% %
457% %
458%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
459%
460% SignatureImage() computes a message digest from an image pixel stream with
461% an implementation of the NIST SHA-256 Message Digest algorithm. This
462% signature uniquely identifies the image and is convenient for determining
463% if an image has been modified or whether two images are identical.
464%
465% The format of the SignatureImage method is:
466%
467% MagickBooleanType SignatureImage(Image *image,ExceptionInfo *exception)
468%
469% A description of each parameter follows:
470%
471% o image: the image.
472%
473% o exception: return any errors or warnings in this structure.
474%
475*/
476MagickExport MagickBooleanType SignatureImage(Image *image,
477 ExceptionInfo *exception)
478{
480 *image_view;
481
482 char
483 *hex_signature;
484
485 float
486 pixel;
487
488 const Quantum
489 *p;
490
492 *signature_info;
493
494 ssize_t
495 y;
496
498 *signature;
499
500 unsigned char
501 *pixels;
502
503 /*
504 Compute image digital signature.
505 */
506 assert(image != (Image *) NULL);
507 assert(image->signature == MagickCoreSignature);
508 if (IsEventLogging() != MagickFalse)
509 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
510 signature_info=AcquireSignatureInfo();
511 signature=AcquireStringInfo(GetPixelChannels(image)*image->columns*
512 sizeof(pixel));
513 image_view=AcquireVirtualCacheView(image,exception);
514 for (y=0; y < (ssize_t) image->rows; y++)
515 {
516 ssize_t
517 x;
518
519 unsigned char
520 *q;
521
522 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
523 if (p == (const Quantum *) NULL)
524 break;
525 SetStringInfoLength(signature,GetPixelChannels(image)*image->columns*
526 sizeof(pixel));
527 pixels=GetStringInfoDatum(signature);
528 q=pixels;
529 for (x=0; x < (ssize_t) image->columns; x++)
530 {
531 ssize_t
532 i;
533
534 if (GetPixelReadMask(image,p) <= (QuantumRange/2))
535 {
536 p+=GetPixelChannels(image);
537 continue;
538 }
539 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
540 {
541 ssize_t
542 j;
543
544 PixelChannel channel = GetPixelChannelChannel(image,i);
545 PixelTrait traits = GetPixelChannelTraits(image,channel);
546 if ((traits & UpdatePixelTrait) == 0)
547 continue;
548 pixel=(float) (QuantumScale*(double) p[i]);
549 if (signature_info->lsb_first == MagickFalse)
550 for (j=(ssize_t) sizeof(pixel)-1; j >= 0; j--)
551 *q++=(unsigned char) ((unsigned char *) &pixel)[j];
552 else
553 for (j=0; j < (ssize_t) sizeof(pixel); j++)
554 *q++=(unsigned char) ((unsigned char *) &pixel)[j];
555 }
556 p+=GetPixelChannels(image);
557 }
558 SetStringInfoLength(signature,(size_t) (q-pixels));
559 UpdateSignature(signature_info,signature);
560 }
561 image_view=DestroyCacheView(image_view);
562 FinalizeSignature(signature_info);
563 hex_signature=StringInfoToHexString(GetSignatureDigest(signature_info));
564 (void) DeleteImageProperty(image,"signature");
565 (void) SetImageProperty(image,"signature",hex_signature,exception);
566 /*
567 Free resources.
568 */
569 hex_signature=DestroyString(hex_signature);
570 signature=DestroyStringInfo(signature);
571 signature_info=DestroySignatureInfo(signature_info);
572 return(MagickTrue);
573}
574
575/*
576%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
577% %
578% %
579% %
580+ T r a n s f o r m S i g n a t u r e %
581% %
582% %
583% %
584%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
585%
586% TransformSignature() transforms the Signature message accumulator.
587%
588% The format of the TransformSignature method is:
589%
590% TransformSignature(SignatureInfo *signature_info)
591%
592% A description of each parameter follows:
593%
594% o signature_info: the address of a structure of type SignatureInfo.
595%
596*/
597static void TransformSignature(SignatureInfo *signature_info)
598{
599#define Ch(x,y,z) (((x) & (y)) ^ (~(x) & (z)))
600#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
601#define RotateRight(x,n) (Trunc32(((x) >> n) | ((x) << (32-n))))
602#define Sigma0(x) (RotateRight(x,7) ^ RotateRight(x,18) ^ Trunc32((x) >> 3))
603#define Sigma1(x) (RotateRight(x,17) ^ RotateRight(x,19) ^ Trunc32((x) >> 10))
604#define Suma0(x) (RotateRight(x,2) ^ RotateRight(x,13) ^ RotateRight(x,22))
605#define Suma1(x) (RotateRight(x,6) ^ RotateRight(x,11) ^ RotateRight(x,25))
606#define Trunc32(x) ((unsigned int) ((x) & 0xffffffffU))
607
608 ssize_t
609 i;
610
611 unsigned char
612 *p;
613
614 ssize_t
615 j;
616
617 static const unsigned int
618 K[64] =
619 {
620 0x428a2f98U, 0x71374491U, 0xb5c0fbcfU, 0xe9b5dba5U, 0x3956c25bU,
621 0x59f111f1U, 0x923f82a4U, 0xab1c5ed5U, 0xd807aa98U, 0x12835b01U,
622 0x243185beU, 0x550c7dc3U, 0x72be5d74U, 0x80deb1feU, 0x9bdc06a7U,
623 0xc19bf174U, 0xe49b69c1U, 0xefbe4786U, 0x0fc19dc6U, 0x240ca1ccU,
624 0x2de92c6fU, 0x4a7484aaU, 0x5cb0a9dcU, 0x76f988daU, 0x983e5152U,
625 0xa831c66dU, 0xb00327c8U, 0xbf597fc7U, 0xc6e00bf3U, 0xd5a79147U,
626 0x06ca6351U, 0x14292967U, 0x27b70a85U, 0x2e1b2138U, 0x4d2c6dfcU,
627 0x53380d13U, 0x650a7354U, 0x766a0abbU, 0x81c2c92eU, 0x92722c85U,
628 0xa2bfe8a1U, 0xa81a664bU, 0xc24b8b70U, 0xc76c51a3U, 0xd192e819U,
629 0xd6990624U, 0xf40e3585U, 0x106aa070U, 0x19a4c116U, 0x1e376c08U,
630 0x2748774cU, 0x34b0bcb5U, 0x391c0cb3U, 0x4ed8aa4aU, 0x5b9cca4fU,
631 0x682e6ff3U, 0x748f82eeU, 0x78a5636fU, 0x84c87814U, 0x8cc70208U,
632 0x90befffaU, 0xa4506cebU, 0xbef9a3f7U, 0xc67178f2U
633 }; /* 32-bit fractional part of the cube root of the first 64 primes */
634
635 unsigned int
636 A = 0,
637 B,
638 C,
639 D,
640 E,
641 F,
642 G,
643 H,
644 shift,
645 T,
646 T1,
647 T2,
648 W[64];
649
650 shift=32;
651 p=GetStringInfoDatum(signature_info->message);
652 if (signature_info->lsb_first == MagickFalse)
653 {
654DisableMSCWarning(4127)
655 if (sizeof(unsigned int) <= 4)
656RestoreMSCWarning
657 for (i=0; i < 16; i++)
658 {
659 T=(*((unsigned int *) p));
660 p+=4;
661 W[i]=Trunc32(T);
662 }
663 else
664 for (i=0; i < 16; i+=2)
665 {
666 T=(*((unsigned int *) p));
667 p+=8;
668 W[i]=Trunc32(T >> shift);
669 W[i+1]=Trunc32(T);
670 }
671 }
672 else
673DisableMSCWarning(4127)
674 if (sizeof(unsigned int) <= 4)
675RestoreMSCWarning
676 for (i=0; i < 16; i++)
677 {
678 T=(*((unsigned int *) p));
679 p+=4;
680 W[i]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
681 ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
682 }
683 else
684 for (i=0; i < 16; i+=2)
685 {
686 T=(*((unsigned int *) p));
687 p+=8;
688 W[i]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
689 ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
690 T>>=shift;
691 W[i+1]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
692 ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
693 }
694 /*
695 Copy accumulator to registers.
696 */
697 A=signature_info->accumulator[0];
698 B=signature_info->accumulator[1];
699 C=signature_info->accumulator[2];
700 D=signature_info->accumulator[3];
701 E=signature_info->accumulator[4];
702 F=signature_info->accumulator[5];
703 G=signature_info->accumulator[6];
704 H=signature_info->accumulator[7];
705 for (i=16; i < 64; i++)
706 W[i]=Trunc32(Sigma1(W[i-2])+W[i-7]+Sigma0(W[i-15])+W[i-16]);
707 for (j=0; j < 64; j++)
708 {
709 T1=Trunc32(H+Suma1(E)+Ch(E,F,G)+K[j]+W[j]);
710 T2=Trunc32(Suma0(A)+Maj(A,B,C));
711 H=G;
712 G=F;
713 F=E;
714 E=Trunc32(D+T1);
715 D=C;
716 C=B;
717 B=A;
718 A=Trunc32(T1+T2);
719 }
720 /*
721 Add registers back to accumulator.
722 */
723 signature_info->accumulator[0]=Trunc32(signature_info->accumulator[0]+A);
724 signature_info->accumulator[1]=Trunc32(signature_info->accumulator[1]+B);
725 signature_info->accumulator[2]=Trunc32(signature_info->accumulator[2]+C);
726 signature_info->accumulator[3]=Trunc32(signature_info->accumulator[3]+D);
727 signature_info->accumulator[4]=Trunc32(signature_info->accumulator[4]+E);
728 signature_info->accumulator[5]=Trunc32(signature_info->accumulator[5]+F);
729 signature_info->accumulator[6]=Trunc32(signature_info->accumulator[6]+G);
730 signature_info->accumulator[7]=Trunc32(signature_info->accumulator[7]+H);
731 /*
732 Reset working registers.
733 */
734 A=0;
735 B=0;
736 C=0;
737 D=0;
738 E=0;
739 F=0;
740 G=0;
741 H=0;
742 T=0;
743 T1=0;
744 T2=0;
745 (void) ResetMagickMemory(W,0,sizeof(W));
746}
747
748/*
749%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
750% %
751% %
752% %
753+ U p d a t e S i g n a t u r e %
754% %
755% %
756% %
757%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
758%
759% UpdateSignature() updates the Signature message accumulator.
760%
761% The format of the UpdateSignature method is:
762%
763% UpdateSignature(SignatureInfo *signature_info,const StringInfo *message)
764%
765% A description of each parameter follows:
766%
767% o signature_info: the address of a structure of type SignatureInfo.
768%
769% o message: the message.
770%
771*/
772MagickPrivate void UpdateSignature(SignatureInfo *signature_info,
773 const StringInfo *message)
774{
775 size_t
776 i;
777
778 unsigned char
779 *p;
780
781 size_t
782 n;
783
784 unsigned int
785 length;
786
787 /*
788 Update the Signature accumulator.
789 */
790 assert(signature_info != (SignatureInfo *) NULL);
791 assert(signature_info->signature == MagickCoreSignature);
792 n=GetStringInfoLength(message);
793 length=Trunc32((unsigned int) (signature_info->low_order+(n << 3)));
794 if (length < signature_info->low_order)
795 signature_info->high_order++;
796 signature_info->low_order=length;
797 signature_info->high_order+=(unsigned int) n >> 29;
798 p=GetStringInfoDatum(message);
799 if (signature_info->extent != 0)
800 {
801 i=GetStringInfoLength(signature_info->message)-signature_info->extent;
802 if (i > n)
803 i=n;
804 (void) memcpy(GetStringInfoDatum(signature_info->message)+
805 signature_info->extent,p,i);
806 n-=i;
807 p+=i;
808 signature_info->extent+=i;
809 if (signature_info->extent != GetStringInfoLength(signature_info->message))
810 return;
811 TransformSignature(signature_info);
812 }
813 while (n >= GetStringInfoLength(signature_info->message))
814 {
815 SetStringInfoDatum(signature_info->message,p);
816 p+=GetStringInfoLength(signature_info->message);
817 n-=GetStringInfoLength(signature_info->message);
818 TransformSignature(signature_info);
819 }
820 (void) memcpy(GetStringInfoDatum(signature_info->message),p,n);
821 signature_info->extent=n;
822}