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