[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [42797] trunk/blender/source/blender: Code refactoring: move MD5 out of imbuf into blenlib.

Brecht Van Lommel brechtvanlommel at pandora.be
Wed Dec 21 14:48:52 CET 2011


Revision: 42797
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=42797
Author:   blendix
Date:     2011-12-21 13:48:51 +0000 (Wed, 21 Dec 2011)
Log Message:
-----------
Code refactoring: move MD5 out of imbuf into blenlib.

Modified Paths:
--------------
    trunk/blender/source/blender/blenlib/CMakeLists.txt
    trunk/blender/source/blender/imbuf/CMakeLists.txt
    trunk/blender/source/blender/imbuf/intern/thumbs.c

Added Paths:
-----------
    trunk/blender/source/blender/blenlib/BLI_md5.h
    trunk/blender/source/blender/blenlib/intern/md5.c

Removed Paths:
-------------
    trunk/blender/source/blender/imbuf/intern/md5.c
    trunk/blender/source/blender/imbuf/intern/md5.h

Added: trunk/blender/source/blender/blenlib/BLI_md5.h
===================================================================
--- trunk/blender/source/blender/blenlib/BLI_md5.h	                        (rev 0)
+++ trunk/blender/source/blender/blenlib/BLI_md5.h	2011-12-21 13:48:51 UTC (rev 42797)
@@ -0,0 +1,45 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef BLI_MD5_H
+#define BLI_MD5_H 
+
+/** \file BLI_md5.h
+ *  \ingroup bli
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+/* Compute MD5 message digest for LEN bytes beginning at BUFFER.  The
+   result is always in little endian byte order, so that a byte-wise
+   output yields to the wanted ASCII representation of the message
+   digest.  */
+
+void *md5_buffer(const char *buffer, size_t len, void *resblock);
+
+/* Compute MD5 message digest for bytes read from STREAM.  The
+   resulting message digest number will be written into the 16 bytes
+   beginning at RESBLOCK.  */
+
+int md5_stream(FILE *stream, void *resblock);
+
+#endif
+

Modified: trunk/blender/source/blender/blenlib/CMakeLists.txt
===================================================================
--- trunk/blender/source/blender/blenlib/CMakeLists.txt	2011-12-21 13:48:35 UTC (rev 42796)
+++ trunk/blender/source/blender/blenlib/CMakeLists.txt	2011-12-21 13:48:51 UTC (rev 42797)
@@ -71,6 +71,7 @@
 	intern/math_rotation.c
 	intern/math_vector.c
 	intern/math_vector_inline.c
+	intern/md5.c
 	intern/noise.c
 	intern/path_util.c
 	intern/pbvh.c
@@ -117,6 +118,7 @@
 	BLI_math_matrix.h
 	BLI_math_rotation.h
 	BLI_math_vector.h
+	BLI_md5.h
 	BLI_memarena.h
 	BLI_mempool.h
 	BLI_noise.h

Copied: trunk/blender/source/blender/blenlib/intern/md5.c (from rev 42796, trunk/blender/source/blender/imbuf/intern/md5.c)
===================================================================
--- trunk/blender/source/blender/blenlib/intern/md5.c	                        (rev 0)
+++ trunk/blender/source/blender/blenlib/intern/md5.c	2011-12-21 13:48:51 UTC (rev 42797)
@@ -0,0 +1,414 @@
+/** \file blender/imbuf/intern/md5.c
+ *  \ingroup imbuf
+ */
+/* md5.c - Functions to compute MD5 message digest of files or memory blocks
+   according to the definition of MD5 in RFC 1321 from April 1992.
+   Copyright (C) 1995 Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* Written by Ulrich Drepper <drepper at gnu.ai.mit.edu>.  */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <sys/types.h>
+
+#if defined HAVE_LIMITS_H || defined _LIBC
+# include <limits.h>
+#endif
+
+/* The following contortions are an attempt to use the C preprocessor
+   to determine an unsigned integral type that is 32 bits wide.  An
+   alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but
+   doing that would require that the configure script compile and *run*
+   the resulting executable.  Locally running cross-compiled executables
+   is usually not possible.  */
+
+#if defined __STDC__ && __STDC__
+# define UINT_MAX_32_BITS 4294967295U
+#else
+# define UINT_MAX_32_BITS 0xFFFFFFFF
+#endif
+
+/* If UINT_MAX isn't defined, assume it's a 32-bit type.
+   This should be valid for all systems GNU cares about because
+   that doesn't include 16-bit systems, and only modern systems
+   (that certainly have <limits.h>) have 64+-bit integral types.  */
+
+#ifndef UINT_MAX
+# define UINT_MAX UINT_MAX_32_BITS
+#endif
+
+#if UINT_MAX == UINT_MAX_32_BITS
+  typedef unsigned int md5_uint32;
+#else
+# if USHRT_MAX == UINT_MAX_32_BITS
+   typedef unsigned short md5_uint32;
+# else
+#  if ULONG_MAX == UINT_MAX_32_BITS
+	typedef unsigned long md5_uint32;
+#  else
+	/* The following line is intended to evoke an error.
+	   Using #error is not portable enough.  */
+	"Cannot determine unsigned 32-bit data type."
+#  endif
+# endif
+#endif
+
+/* Structure to save state of computation between the single steps.  */
+struct md5_ctx
+{
+  md5_uint32 A;
+  md5_uint32 B;
+  md5_uint32 C;
+  md5_uint32 D;
+};
+
+/*
+ * The following three functions are build up the low level used in
+ * the functions `md5_stream' and `md5_buffer'.
+ */
+
+/* Initialize structure containing state of computation.
+   (RFC 1321, 3.3: Step 3)  */
+static void md5_init_ctx(struct md5_ctx *ctx);
+
+/* Starting with the result of former calls of this function (or the
+   initialzation function update the context for the next LEN bytes
+   starting at BUFFER.
+   It is necessary that LEN is a multiple of 64!!! */
+static void md5_process_block(const void *buffer, size_t len, struct md5_ctx *ctx);
+
+/* Put result from CTX in first 16 bytes following RESBUF.  The result is
+   always in little endian byte order, so that a byte-wise output yields
+   to the wanted ASCII representation of the message digest.  */
+static void *md5_read_ctx(const struct md5_ctx *ctx, void *resbuf);
+
+
+#ifdef __BIG_ENDIAN__
+#  define SWAP(n)							\
+	(((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
+#else
+#  define SWAP(n) (n)
+#endif
+
+
+/* This array contains the bytes used to pad the buffer to the next
+   64-byte boundary.  (RFC 1321, 3.1: Step 1)  */
+static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ...  */ };
+
+
+/* Initialize structure containing state of computation.
+   (RFC 1321, 3.3: Step 3)  */
+static void md5_init_ctx(struct md5_ctx *ctx)
+{
+  ctx->A = 0x67452301;
+  ctx->B = 0xefcdab89;
+  ctx->C = 0x98badcfe;
+  ctx->D = 0x10325476;
+}
+
+/* Put result from CTX in first 16 bytes following RESBUF.  The result must
+   be in little endian byte order.  */
+static void *md5_read_ctx(const struct md5_ctx *ctx, void *resbuf)
+{
+  ((md5_uint32 *) resbuf)[0] = SWAP (ctx->A);
+  ((md5_uint32 *) resbuf)[1] = SWAP (ctx->B);
+  ((md5_uint32 *) resbuf)[2] = SWAP (ctx->C);
+  ((md5_uint32 *) resbuf)[3] = SWAP (ctx->D);
+
+  return resbuf;
+}
+
+/* Compute MD5 message digest for bytes read from STREAM.  The
+   resulting message digest number will be written into the 16 bytes
+   beginning at RESBLOCK.  */
+int md5_stream(FILE *stream, void *resblock)
+{
+  /* Important: BLOCKSIZE must be a multiple of 64.  */
+#define BLOCKSIZE 4096
+  struct md5_ctx ctx;
+  md5_uint32 len[2];
+  char buffer[BLOCKSIZE + 72];
+  size_t pad, sum;
+
+  /* Initialize the computation context.  */
+  md5_init_ctx (&ctx);
+
+  len[0] = 0;
+  len[1] = 0;
+
+  /* Iterate over full file contents.  */
+  while (1)
+	{
+	  /* We read the file in blocks of BLOCKSIZE bytes.  One call of the
+	 computation function processes the whole buffer so that with the
+	 next round of the loop another block can be read.  */
+	  size_t n;
+	  sum = 0;
+
+	  /* Read block.  Take care for partial reads.  */
+	  do
+	{
+	  n = fread (buffer, 1, BLOCKSIZE - sum, stream);
+
+	  sum += n;
+	}
+	  while (sum < BLOCKSIZE && n != 0);
+	  if (n == 0 && ferror (stream))
+		return 1;
+
+	  /* RFC 1321 specifies the possible length of the file up to 2^64 bits.
+	 Here we only compute the number of bytes.  Do a double word
+		 increment.  */
+	  len[0] += sum;
+	  if (len[0] < sum)
+	++len[1];
+
+	  /* If end of file is reached, end the loop.  */
+	  if (n == 0)
+	break;
+
+	  /* Process buffer with BLOCKSIZE bytes.  Note that
+			BLOCKSIZE % 64 == 0
+	   */
+	  md5_process_block (buffer, BLOCKSIZE, &ctx);
+	}
+
+  /* We can copy 64 byte because the buffer is always big enough.  FILLBUF
+	 contains the needed bits.  */
+  memcpy (&buffer[sum], fillbuf, 64);
+
+  /* Compute amount of padding bytes needed.  Alignment is done to
+		(N + PAD) % 64 == 56
+	 There is always at least one byte padded.  I.e. even the alignment
+	 is correctly aligned 64 padding bytes are added.  */
+  pad = sum & 63;
+  pad = pad >= 56 ? 64 + 56 - pad : 56 - pad;
+
+  /* Put the 64-bit file length in *bits* at the end of the buffer.  */
+  *(md5_uint32 *) &buffer[sum + pad] = SWAP (len[0] << 3);
+  *(md5_uint32 *) &buffer[sum + pad + 4] = SWAP ((len[1] << 3)
+						 | (len[0] >> 29));
+
+  /* Process last bytes.  */
+  md5_process_block (buffer, sum + pad + 8, &ctx);
+
+  /* Construct result in desired memory.  */
+  md5_read_ctx (&ctx, resblock);
+  return 0;
+}
+
+/* Compute MD5 message digest for LEN bytes beginning at BUFFER.  The
+   result is always in little endian byte order, so that a byte-wise
+   output yields to the wanted ASCII representation of the message
+   digest.  */
+void *md5_buffer(const char *buffer, size_t len, void *resblock)
+{
+  struct md5_ctx ctx;
+  char restbuf[64 + 72];
+  size_t blocks = len & ~63;
+  size_t pad, rest;
+
+  /* Initialize the computation context.  */
+  md5_init_ctx (&ctx);
+
+  /* Process whole buffer but last len % 64 bytes.  */
+  md5_process_block (buffer, blocks, &ctx);
+
+  /* REST bytes are not processed yet.  */
+  rest = len - blocks;
+  /* Copy to own buffer.  */
+  memcpy (restbuf, &buffer[blocks], rest);
+  /* Append needed fill bytes at end of buffer.  We can copy 64 byte
+	 because the buffer is always big enough.  */
+  memcpy (&restbuf[rest], fillbuf, 64);
+
+  /* PAD bytes are used for padding to correct alignment.  Note that
+	 always at least one byte is padded.  */

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list