00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef IMAGE_HASH_C_DEFINED
00039 #define IMAGE_HASH_C_DEFINED
00040
00041 #include "Image/Hash.H"
00042
00043 #include "Image/Image.H"
00044 #include "Image/Pixels.H"
00045 #include "Util/md5.H"
00046 #include "Util/sha1.H"
00047 #include "Util/sha2.H"
00048 #include "rutz/compat_snprintf.h"
00049 #include "rutz/trace.h"
00050
00051 #include <cctype>
00052
00053 namespace
00054 {
00055 template <class T>
00056 Digest<16> md5helper(const Image<T>* img, const void* extra, size_t nextra)
00057 {
00058 GVX_TRACE(__PRETTY_FUNCTION__);
00059 md5_context ctx;
00060 md5_starts(&ctx);
00061 md5_update(&ctx,
00062 reinterpret_cast<const byte*>(img->getArrayPtr()),
00063 img->getSize() * sizeof(T));
00064 if (extra != 0 && nextra > 0)
00065 md5_update(&ctx, static_cast<const byte*>(extra), nextra);
00066 Digest<16> result;
00067 md5_finish(&ctx, result.buffer);
00068 return result;
00069 }
00070
00071 template <class T>
00072 Digest<20> sha1helper(const Image<T>* img, const void* extra, size_t nextra)
00073 {
00074 GVX_TRACE(__PRETTY_FUNCTION__);
00075 sha1_context ctx;
00076 sha1_starts(&ctx);
00077 sha1_update(&ctx,
00078 reinterpret_cast<const byte*>(img->getArrayPtr()),
00079 img->getSize() * sizeof(T));
00080 if (extra != 0 && nextra > 0)
00081 sha1_update(&ctx, static_cast<const byte*>(extra), nextra);
00082 Digest<20> result;
00083 sha1_finish(&ctx, result.buffer);
00084 return result;
00085 }
00086
00087 template <class T>
00088 Digest<32> sha256helper(const Image<T>* img, const void* extra, size_t nextra)
00089 {
00090 GVX_TRACE(__PRETTY_FUNCTION__);
00091 sha256_context ctx;
00092 sha256_starts(&ctx);
00093 sha256_update(&ctx,
00094 reinterpret_cast<const byte*>(img->getArrayPtr()),
00095 img->getSize() * sizeof(T));
00096 if (extra != 0 && nextra > 0)
00097 sha256_update(&ctx, static_cast<const byte*>(extra), nextra);
00098 Digest<32> result;
00099 sha256_finish(&ctx, result.buffer);
00100 return result;
00101 }
00102 }
00103
00104 std::string digestFormatHelper(const byte* buf, unsigned int n)
00105 {
00106 char fmt[n*2 + 1];
00107 for (unsigned int i = 0; i < n; ++i)
00108 {
00109
00110
00111
00112 snprintf(&fmt[i*2], 3, "%02x", int(buf[i]));
00113 }
00114 return std::string(&fmt[0]);
00115 }
00116
00117 void digestScanHelper(const std::string& s, byte* buf, unsigned int n)
00118 {
00119 if (s.length() != n*2)
00120 LFATAL("expected string of length %u in order to generate a "
00121 "Digest<%u>, but got '%s' of length %"ZU,
00122 n*2, n, s.c_str(), s.length());
00123
00124 for (unsigned int i = 0; i < n; ++i)
00125 {
00126 buf[i] = 0;
00127
00128 for (unsigned int j = 0; j < 2; ++j)
00129 {
00130 buf[i] *= 16;
00131
00132 switch (tolower(s[i*2+j]))
00133 {
00134 case '0': buf[i] += 0; break;
00135 case '1': buf[i] += 1; break;
00136 case '2': buf[i] += 2; break;
00137 case '3': buf[i] += 3; break;
00138 case '4': buf[i] += 4; break;
00139 case '5': buf[i] += 5; break;
00140 case '6': buf[i] += 6; break;
00141 case '7': buf[i] += 7; break;
00142 case '8': buf[i] += 8; break;
00143 case '9': buf[i] += 9; break;
00144 case 'a': buf[i] += 10; break;
00145 case 'b': buf[i] += 11; break;
00146 case 'c': buf[i] += 12; break;
00147 case 'd': buf[i] += 13; break;
00148 case 'e': buf[i] += 14; break;
00149 case 'f': buf[i] += 15; break;
00150 default:
00151 LFATAL("invalid hex digit '%c' at position %u in hash string '%s'",
00152 s[i*2+j], i*2+j, s.c_str());
00153 }
00154 }
00155 }
00156 }
00157
00158
00159 Digest<16> md5byte(const Image<byte>* img, const void* extra, size_t nextra)
00160 { return md5helper<byte>(img, extra, nextra); }
00161
00162 Digest<16> md5float(const Image<float>* img, const void* extra, size_t nextra)
00163 { return md5helper<float>(img, extra, nextra); }
00164
00165 Digest<16> md5rgb(const Image<PixRGB<byte> >* img, const void* extra, size_t nextra)
00166 { return md5helper<PixRGB<byte> >(img, extra, nextra); }
00167
00168
00169 Digest<20> sha1byte(const Image<byte>* img, const void* extra, size_t nextra)
00170 { return sha1helper<byte>(img, extra, nextra); }
00171
00172 Digest<20> sha1float(const Image<float>* img, const void* extra, size_t nextra)
00173 { return sha1helper<float>(img, extra, nextra); }
00174
00175 Digest<20> sha1rgb(const Image<PixRGB<byte> >* img, const void* extra, size_t nextra)
00176 { return sha1helper<PixRGB<byte> >(img, extra, nextra); }
00177
00178
00179 Digest<32> sha256byte(const Image<byte>* img, const void* extra, size_t nextra)
00180 { return sha256helper<byte>(img, extra, nextra); }
00181
00182 Digest<32> sha256float(const Image<float>* img, const void* extra, size_t nextra)
00183 { return sha256helper<float>(img, extra, nextra); }
00184
00185 Digest<32> sha256rgb(const Image<PixRGB<byte> >* img, const void* extra, size_t nextra)
00186 { return sha256helper<PixRGB<byte> >(img, extra, nextra); }
00187
00188
00189
00190
00191
00192
00193
00194 #endif // IMAGE_HASH_C_DEFINED