xref: /aosp_15_r20/external/libdav1d/tools/output/md5.c (revision c09093415860a1c2373dacd84c4fde00c507cdfd)
1*c0909341SAndroid Build Coastguard Worker /*
2*c0909341SAndroid Build Coastguard Worker  * Copyright © 2018, VideoLAN and dav1d authors
3*c0909341SAndroid Build Coastguard Worker  * Copyright © 2018, Two Orioles, LLC
4*c0909341SAndroid Build Coastguard Worker  * All rights reserved.
5*c0909341SAndroid Build Coastguard Worker  *
6*c0909341SAndroid Build Coastguard Worker  * Redistribution and use in source and binary forms, with or without
7*c0909341SAndroid Build Coastguard Worker  * modification, are permitted provided that the following conditions are met:
8*c0909341SAndroid Build Coastguard Worker  *
9*c0909341SAndroid Build Coastguard Worker  * 1. Redistributions of source code must retain the above copyright notice, this
10*c0909341SAndroid Build Coastguard Worker  *    list of conditions and the following disclaimer.
11*c0909341SAndroid Build Coastguard Worker  *
12*c0909341SAndroid Build Coastguard Worker  * 2. Redistributions in binary form must reproduce the above copyright notice,
13*c0909341SAndroid Build Coastguard Worker  *    this list of conditions and the following disclaimer in the documentation
14*c0909341SAndroid Build Coastguard Worker  *    and/or other materials provided with the distribution.
15*c0909341SAndroid Build Coastguard Worker  *
16*c0909341SAndroid Build Coastguard Worker  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17*c0909341SAndroid Build Coastguard Worker  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18*c0909341SAndroid Build Coastguard Worker  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19*c0909341SAndroid Build Coastguard Worker  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
20*c0909341SAndroid Build Coastguard Worker  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21*c0909341SAndroid Build Coastguard Worker  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22*c0909341SAndroid Build Coastguard Worker  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23*c0909341SAndroid Build Coastguard Worker  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24*c0909341SAndroid Build Coastguard Worker  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25*c0909341SAndroid Build Coastguard Worker  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*c0909341SAndroid Build Coastguard Worker  */
27*c0909341SAndroid Build Coastguard Worker 
28*c0909341SAndroid Build Coastguard Worker #include "config.h"
29*c0909341SAndroid Build Coastguard Worker 
30*c0909341SAndroid Build Coastguard Worker #include <errno.h>
31*c0909341SAndroid Build Coastguard Worker #include <stdio.h>
32*c0909341SAndroid Build Coastguard Worker #include <stdlib.h>
33*c0909341SAndroid Build Coastguard Worker #include <string.h>
34*c0909341SAndroid Build Coastguard Worker 
35*c0909341SAndroid Build Coastguard Worker #include "common/intops.h"
36*c0909341SAndroid Build Coastguard Worker 
37*c0909341SAndroid Build Coastguard Worker #include "output/muxer.h"
38*c0909341SAndroid Build Coastguard Worker 
39*c0909341SAndroid Build Coastguard Worker static const uint32_t k[64] = {
40*c0909341SAndroid Build Coastguard Worker     0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
41*c0909341SAndroid Build Coastguard Worker     0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
42*c0909341SAndroid Build Coastguard Worker     0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
43*c0909341SAndroid Build Coastguard Worker     0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
44*c0909341SAndroid Build Coastguard Worker     0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
45*c0909341SAndroid Build Coastguard Worker     0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
46*c0909341SAndroid Build Coastguard Worker     0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
47*c0909341SAndroid Build Coastguard Worker     0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
48*c0909341SAndroid Build Coastguard Worker     0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
49*c0909341SAndroid Build Coastguard Worker     0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
50*c0909341SAndroid Build Coastguard Worker     0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
51*c0909341SAndroid Build Coastguard Worker     0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
52*c0909341SAndroid Build Coastguard Worker     0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
53*c0909341SAndroid Build Coastguard Worker     0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
54*c0909341SAndroid Build Coastguard Worker     0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
55*c0909341SAndroid Build Coastguard Worker     0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
56*c0909341SAndroid Build Coastguard Worker };
57*c0909341SAndroid Build Coastguard Worker 
58*c0909341SAndroid Build Coastguard Worker #if ENDIANNESS_BIG
59*c0909341SAndroid Build Coastguard Worker #define NE2LE_32(x) (((x & 0x00ff) << 24) |\
60*c0909341SAndroid Build Coastguard Worker                      ((x & 0xff00) <<  8) |\
61*c0909341SAndroid Build Coastguard Worker                      ((x >>  8) & 0xff00) |\
62*c0909341SAndroid Build Coastguard Worker                      ((x >> 24) & 0x00ff))
63*c0909341SAndroid Build Coastguard Worker 
64*c0909341SAndroid Build Coastguard Worker #define NE2LE_64(x) (((x & 0x000000ff) << 56) |\
65*c0909341SAndroid Build Coastguard Worker                      ((x & 0x0000ff00) << 40) |\
66*c0909341SAndroid Build Coastguard Worker                      ((x & 0x00ff0000) << 24) |\
67*c0909341SAndroid Build Coastguard Worker                      ((x & 0xff000000) <<  8) |\
68*c0909341SAndroid Build Coastguard Worker                      ((x >>  8) & 0xff000000) |\
69*c0909341SAndroid Build Coastguard Worker                      ((x >> 24) & 0x00ff0000) |\
70*c0909341SAndroid Build Coastguard Worker                      ((x >> 40) & 0x0000ff00) |\
71*c0909341SAndroid Build Coastguard Worker                      ((x >> 56) & 0x000000ff))
72*c0909341SAndroid Build Coastguard Worker 
73*c0909341SAndroid Build Coastguard Worker #else
74*c0909341SAndroid Build Coastguard Worker #define NE2LE_32(x) (x)
75*c0909341SAndroid Build Coastguard Worker #define NE2LE_64(x) (x)
76*c0909341SAndroid Build Coastguard Worker #endif
77*c0909341SAndroid Build Coastguard Worker 
78*c0909341SAndroid Build Coastguard Worker typedef struct MuxerPriv {
79*c0909341SAndroid Build Coastguard Worker     uint32_t abcd[4];
80*c0909341SAndroid Build Coastguard Worker     union {
81*c0909341SAndroid Build Coastguard Worker         uint8_t data[64];
82*c0909341SAndroid Build Coastguard Worker         uint32_t data32[16];
83*c0909341SAndroid Build Coastguard Worker     };
84*c0909341SAndroid Build Coastguard Worker     uint64_t len;
85*c0909341SAndroid Build Coastguard Worker     FILE *f;
86*c0909341SAndroid Build Coastguard Worker #if ENDIANNESS_BIG
87*c0909341SAndroid Build Coastguard Worker     uint8_t *bswap;
88*c0909341SAndroid Build Coastguard Worker     int bswap_w;
89*c0909341SAndroid Build Coastguard Worker #endif
90*c0909341SAndroid Build Coastguard Worker } MD5Context;
91*c0909341SAndroid Build Coastguard Worker 
md5_open(MD5Context * const md5,const char * const file,const Dav1dPictureParameters * const p,const unsigned fps[2])92*c0909341SAndroid Build Coastguard Worker static int md5_open(MD5Context *const md5, const char *const file,
93*c0909341SAndroid Build Coastguard Worker                     const Dav1dPictureParameters *const p,
94*c0909341SAndroid Build Coastguard Worker                     const unsigned fps[2])
95*c0909341SAndroid Build Coastguard Worker {
96*c0909341SAndroid Build Coastguard Worker     if (!strcmp(file, "-")) {
97*c0909341SAndroid Build Coastguard Worker         md5->f = stdout;
98*c0909341SAndroid Build Coastguard Worker     } else if (!(md5->f = fopen(file, "wb"))) {
99*c0909341SAndroid Build Coastguard Worker         fprintf(stderr, "Failed to open %s: %s\n", file, strerror(errno));
100*c0909341SAndroid Build Coastguard Worker         return -1;
101*c0909341SAndroid Build Coastguard Worker     }
102*c0909341SAndroid Build Coastguard Worker 
103*c0909341SAndroid Build Coastguard Worker #if ENDIANNESS_BIG
104*c0909341SAndroid Build Coastguard Worker     md5->bswap = NULL;
105*c0909341SAndroid Build Coastguard Worker     md5->bswap_w = 0;
106*c0909341SAndroid Build Coastguard Worker #endif
107*c0909341SAndroid Build Coastguard Worker 
108*c0909341SAndroid Build Coastguard Worker     md5->abcd[0] = 0x67452301;
109*c0909341SAndroid Build Coastguard Worker     md5->abcd[1] = 0xefcdab89;
110*c0909341SAndroid Build Coastguard Worker     md5->abcd[2] = 0x98badcfe;
111*c0909341SAndroid Build Coastguard Worker     md5->abcd[3] = 0x10325476;
112*c0909341SAndroid Build Coastguard Worker     md5->len = 0;
113*c0909341SAndroid Build Coastguard Worker 
114*c0909341SAndroid Build Coastguard Worker     return 0;
115*c0909341SAndroid Build Coastguard Worker }
116*c0909341SAndroid Build Coastguard Worker 
leftrotate(const uint32_t x,const int c)117*c0909341SAndroid Build Coastguard Worker static inline uint32_t leftrotate(const uint32_t x, const int c) {
118*c0909341SAndroid Build Coastguard Worker     return (x << c) | (x >> (32 - c));
119*c0909341SAndroid Build Coastguard Worker }
120*c0909341SAndroid Build Coastguard Worker 
121*c0909341SAndroid Build Coastguard Worker #define F(i) do { \
122*c0909341SAndroid Build Coastguard Worker     a = b + leftrotate(a + ((b & c) | (~b & d)) + k[i + 0] + NE2LE_32(data[i + 0]),  7); \
123*c0909341SAndroid Build Coastguard Worker     d = a + leftrotate(d + ((a & b) | (~a & c)) + k[i + 1] + NE2LE_32(data[i + 1]), 12); \
124*c0909341SAndroid Build Coastguard Worker     c = d + leftrotate(c + ((d & a) | (~d & b)) + k[i + 2] + NE2LE_32(data[i + 2]), 17); \
125*c0909341SAndroid Build Coastguard Worker     b = c + leftrotate(b + ((c & d) | (~c & a)) + k[i + 3] + NE2LE_32(data[i + 3]), 22); \
126*c0909341SAndroid Build Coastguard Worker } while (0)
127*c0909341SAndroid Build Coastguard Worker 
128*c0909341SAndroid Build Coastguard Worker #define G(i) do { \
129*c0909341SAndroid Build Coastguard Worker     a = b + leftrotate(a + ((d & b) | (~d & c)) + k[i + 0] + NE2LE_32(data[(i +  1) & 15]),  5); \
130*c0909341SAndroid Build Coastguard Worker     d = a + leftrotate(d + ((c & a) | (~c & b)) + k[i + 1] + NE2LE_32(data[(i +  6) & 15]),  9); \
131*c0909341SAndroid Build Coastguard Worker     c = d + leftrotate(c + ((b & d) | (~b & a)) + k[i + 2] + NE2LE_32(data[(i + 11) & 15]), 14); \
132*c0909341SAndroid Build Coastguard Worker     b = c + leftrotate(b + ((a & c) | (~a & d)) + k[i + 3] + NE2LE_32(data[(i +  0) & 15]), 20); \
133*c0909341SAndroid Build Coastguard Worker } while (0)
134*c0909341SAndroid Build Coastguard Worker 
135*c0909341SAndroid Build Coastguard Worker #define H(i) do { \
136*c0909341SAndroid Build Coastguard Worker     a = b + leftrotate(a + (b ^ c ^ d) + k[i + 0] + NE2LE_32(data[( 5 - i) & 15]),  4); \
137*c0909341SAndroid Build Coastguard Worker     d = a + leftrotate(d + (a ^ b ^ c) + k[i + 1] + NE2LE_32(data[( 8 - i) & 15]), 11); \
138*c0909341SAndroid Build Coastguard Worker     c = d + leftrotate(c + (d ^ a ^ b) + k[i + 2] + NE2LE_32(data[(11 - i) & 15]), 16); \
139*c0909341SAndroid Build Coastguard Worker     b = c + leftrotate(b + (c ^ d ^ a) + k[i + 3] + NE2LE_32(data[(14 - i) & 15]), 23); \
140*c0909341SAndroid Build Coastguard Worker } while (0)
141*c0909341SAndroid Build Coastguard Worker 
142*c0909341SAndroid Build Coastguard Worker #define I(i) do { \
143*c0909341SAndroid Build Coastguard Worker     a = b + leftrotate(a + (c ^ (b | ~d)) + k[i + 0] + NE2LE_32(data[( 0 - i) & 15]),  6); \
144*c0909341SAndroid Build Coastguard Worker     d = a + leftrotate(d + (b ^ (a | ~c)) + k[i + 1] + NE2LE_32(data[( 7 - i) & 15]), 10); \
145*c0909341SAndroid Build Coastguard Worker     c = d + leftrotate(c + (a ^ (d | ~b)) + k[i + 2] + NE2LE_32(data[(14 - i) & 15]), 15); \
146*c0909341SAndroid Build Coastguard Worker     b = c + leftrotate(b + (d ^ (c | ~a)) + k[i + 3] + NE2LE_32(data[( 5 - i) & 15]), 21); \
147*c0909341SAndroid Build Coastguard Worker } while (0)
148*c0909341SAndroid Build Coastguard Worker 
md5_body(MD5Context * const md5,const uint32_t * const data)149*c0909341SAndroid Build Coastguard Worker static void md5_body(MD5Context *const md5, const uint32_t *const data) {
150*c0909341SAndroid Build Coastguard Worker     uint32_t a = md5->abcd[0];
151*c0909341SAndroid Build Coastguard Worker     uint32_t b = md5->abcd[1];
152*c0909341SAndroid Build Coastguard Worker     uint32_t c = md5->abcd[2];
153*c0909341SAndroid Build Coastguard Worker     uint32_t d = md5->abcd[3];
154*c0909341SAndroid Build Coastguard Worker 
155*c0909341SAndroid Build Coastguard Worker     F( 0); F( 4); F( 8); F(12);
156*c0909341SAndroid Build Coastguard Worker     G(16); G(20); G(24); G(28);
157*c0909341SAndroid Build Coastguard Worker     H(32); H(36); H(40); H(44);
158*c0909341SAndroid Build Coastguard Worker     I(48); I(52); I(56); I(60);
159*c0909341SAndroid Build Coastguard Worker 
160*c0909341SAndroid Build Coastguard Worker     md5->abcd[0] += a;
161*c0909341SAndroid Build Coastguard Worker     md5->abcd[1] += b;
162*c0909341SAndroid Build Coastguard Worker     md5->abcd[2] += c;
163*c0909341SAndroid Build Coastguard Worker     md5->abcd[3] += d;
164*c0909341SAndroid Build Coastguard Worker }
165*c0909341SAndroid Build Coastguard Worker 
md5_update(MD5Context * const md5,const uint8_t * data,unsigned len)166*c0909341SAndroid Build Coastguard Worker static void md5_update(MD5Context *const md5, const uint8_t *data, unsigned len) {
167*c0909341SAndroid Build Coastguard Worker     if (!len) return;
168*c0909341SAndroid Build Coastguard Worker 
169*c0909341SAndroid Build Coastguard Worker     if (md5->len & 63) {
170*c0909341SAndroid Build Coastguard Worker         const unsigned tmp = umin(len, 64 - (md5->len & 63));
171*c0909341SAndroid Build Coastguard Worker 
172*c0909341SAndroid Build Coastguard Worker         memcpy(&md5->data[md5->len & 63], data, tmp);
173*c0909341SAndroid Build Coastguard Worker         len -= tmp;
174*c0909341SAndroid Build Coastguard Worker         data += tmp;
175*c0909341SAndroid Build Coastguard Worker         md5->len += tmp;
176*c0909341SAndroid Build Coastguard Worker         if (!(md5->len & 63))
177*c0909341SAndroid Build Coastguard Worker             md5_body(md5, md5->data32);
178*c0909341SAndroid Build Coastguard Worker     }
179*c0909341SAndroid Build Coastguard Worker 
180*c0909341SAndroid Build Coastguard Worker     while (len >= 64) {
181*c0909341SAndroid Build Coastguard Worker         memcpy(md5->data, data, 64);
182*c0909341SAndroid Build Coastguard Worker         md5_body(md5, md5->data32);
183*c0909341SAndroid Build Coastguard Worker         md5->len += 64;
184*c0909341SAndroid Build Coastguard Worker         data += 64;
185*c0909341SAndroid Build Coastguard Worker         len -= 64;
186*c0909341SAndroid Build Coastguard Worker     }
187*c0909341SAndroid Build Coastguard Worker 
188*c0909341SAndroid Build Coastguard Worker     if (len) {
189*c0909341SAndroid Build Coastguard Worker         memcpy(md5->data, data, len);
190*c0909341SAndroid Build Coastguard Worker         md5->len += len;
191*c0909341SAndroid Build Coastguard Worker     }
192*c0909341SAndroid Build Coastguard Worker }
193*c0909341SAndroid Build Coastguard Worker 
md5_write(MD5Context * const md5,Dav1dPicture * const p)194*c0909341SAndroid Build Coastguard Worker static int md5_write(MD5Context *const md5, Dav1dPicture *const p) {
195*c0909341SAndroid Build Coastguard Worker     const int hbd = p->p.bpc > 8;
196*c0909341SAndroid Build Coastguard Worker     const int w = p->p.w, h = p->p.h;
197*c0909341SAndroid Build Coastguard Worker     uint8_t *yptr = p->data[0];
198*c0909341SAndroid Build Coastguard Worker 
199*c0909341SAndroid Build Coastguard Worker #if ENDIANNESS_BIG
200*c0909341SAndroid Build Coastguard Worker     if (hbd && (!md5->bswap || md5->bswap_w < p->p.w)) {
201*c0909341SAndroid Build Coastguard Worker         free(md5->bswap);
202*c0909341SAndroid Build Coastguard Worker         md5->bswap_w = 0;
203*c0909341SAndroid Build Coastguard Worker         md5->bswap = malloc(p->p.w << 1);
204*c0909341SAndroid Build Coastguard Worker         if (!md5->bswap) return -1;
205*c0909341SAndroid Build Coastguard Worker         md5->bswap_w = p->p.w;
206*c0909341SAndroid Build Coastguard Worker     }
207*c0909341SAndroid Build Coastguard Worker #endif
208*c0909341SAndroid Build Coastguard Worker 
209*c0909341SAndroid Build Coastguard Worker     for (int y = 0; y < h; y++) {
210*c0909341SAndroid Build Coastguard Worker #if ENDIANNESS_BIG
211*c0909341SAndroid Build Coastguard Worker         if (hbd) {
212*c0909341SAndroid Build Coastguard Worker             for (int x = 0; x < w; x++) {
213*c0909341SAndroid Build Coastguard Worker                 md5->bswap[2 * x + 1] = yptr[2 * x];
214*c0909341SAndroid Build Coastguard Worker                 md5->bswap[2 * x]     = yptr[2 * x + 1];
215*c0909341SAndroid Build Coastguard Worker             }
216*c0909341SAndroid Build Coastguard Worker             md5_update(md5, md5->bswap, w << hbd);
217*c0909341SAndroid Build Coastguard Worker         } else
218*c0909341SAndroid Build Coastguard Worker #endif
219*c0909341SAndroid Build Coastguard Worker         md5_update(md5, yptr, w << hbd);
220*c0909341SAndroid Build Coastguard Worker         yptr += p->stride[0];
221*c0909341SAndroid Build Coastguard Worker     }
222*c0909341SAndroid Build Coastguard Worker 
223*c0909341SAndroid Build Coastguard Worker     if (p->p.layout != DAV1D_PIXEL_LAYOUT_I400) {
224*c0909341SAndroid Build Coastguard Worker         const int ss_ver = p->p.layout == DAV1D_PIXEL_LAYOUT_I420;
225*c0909341SAndroid Build Coastguard Worker         const int ss_hor = p->p.layout != DAV1D_PIXEL_LAYOUT_I444;
226*c0909341SAndroid Build Coastguard Worker         const int cw = (w + ss_hor) >> ss_hor;
227*c0909341SAndroid Build Coastguard Worker         const int ch = (h + ss_ver) >> ss_ver;
228*c0909341SAndroid Build Coastguard Worker         for (int pl = 1; pl <= 2; pl++) {
229*c0909341SAndroid Build Coastguard Worker             uint8_t *uvptr = p->data[pl];
230*c0909341SAndroid Build Coastguard Worker 
231*c0909341SAndroid Build Coastguard Worker             for (int y = 0; y < ch; y++) {
232*c0909341SAndroid Build Coastguard Worker #if ENDIANNESS_BIG
233*c0909341SAndroid Build Coastguard Worker                 if (hbd) {
234*c0909341SAndroid Build Coastguard Worker                     for (int x = 0; x < cw; x++){
235*c0909341SAndroid Build Coastguard Worker                         md5->bswap[2 * x + 1] = uvptr[2 * x];
236*c0909341SAndroid Build Coastguard Worker                         md5->bswap[2 * x]     = uvptr[2 * x + 1];
237*c0909341SAndroid Build Coastguard Worker                     }
238*c0909341SAndroid Build Coastguard Worker                     md5_update(md5, md5->bswap, cw << hbd);
239*c0909341SAndroid Build Coastguard Worker                 } else
240*c0909341SAndroid Build Coastguard Worker #endif
241*c0909341SAndroid Build Coastguard Worker                 md5_update(md5, uvptr, cw << hbd);
242*c0909341SAndroid Build Coastguard Worker                 uvptr += p->stride[1];
243*c0909341SAndroid Build Coastguard Worker             }
244*c0909341SAndroid Build Coastguard Worker         }
245*c0909341SAndroid Build Coastguard Worker     }
246*c0909341SAndroid Build Coastguard Worker 
247*c0909341SAndroid Build Coastguard Worker     dav1d_picture_unref(p);
248*c0909341SAndroid Build Coastguard Worker 
249*c0909341SAndroid Build Coastguard Worker     return 0;
250*c0909341SAndroid Build Coastguard Worker }
251*c0909341SAndroid Build Coastguard Worker 
md5_finish(MD5Context * const md5)252*c0909341SAndroid Build Coastguard Worker static void md5_finish(MD5Context *const md5) {
253*c0909341SAndroid Build Coastguard Worker     static const uint8_t bit[2] = { 0x80, 0x00 };
254*c0909341SAndroid Build Coastguard Worker     const uint64_t len = NE2LE_64(md5->len << 3);
255*c0909341SAndroid Build Coastguard Worker 
256*c0909341SAndroid Build Coastguard Worker     md5_update(md5, &bit[0], 1);
257*c0909341SAndroid Build Coastguard Worker     while ((md5->len & 63) != 56)
258*c0909341SAndroid Build Coastguard Worker         md5_update(md5, &bit[1], 1);
259*c0909341SAndroid Build Coastguard Worker     md5_update(md5, (const uint8_t *) &len, 8);
260*c0909341SAndroid Build Coastguard Worker }
261*c0909341SAndroid Build Coastguard Worker 
md5_close(MD5Context * const md5)262*c0909341SAndroid Build Coastguard Worker static void md5_close(MD5Context *const md5) {
263*c0909341SAndroid Build Coastguard Worker     md5_finish(md5);
264*c0909341SAndroid Build Coastguard Worker     for (int i = 0; i < 4; i++)
265*c0909341SAndroid Build Coastguard Worker         fprintf(md5->f, "%2.2x%2.2x%2.2x%2.2x",
266*c0909341SAndroid Build Coastguard Worker                 md5->abcd[i] & 0xff,
267*c0909341SAndroid Build Coastguard Worker                 (md5->abcd[i] >> 8) & 0xff,
268*c0909341SAndroid Build Coastguard Worker                 (md5->abcd[i] >> 16) & 0xff,
269*c0909341SAndroid Build Coastguard Worker                 md5->abcd[i] >> 24);
270*c0909341SAndroid Build Coastguard Worker     fprintf(md5->f, "\n");
271*c0909341SAndroid Build Coastguard Worker 
272*c0909341SAndroid Build Coastguard Worker #if ENDIANNESS_BIG
273*c0909341SAndroid Build Coastguard Worker     free(md5->bswap);
274*c0909341SAndroid Build Coastguard Worker     md5->bswap_w = 0;
275*c0909341SAndroid Build Coastguard Worker #endif
276*c0909341SAndroid Build Coastguard Worker 
277*c0909341SAndroid Build Coastguard Worker     if (md5->f != stdout)
278*c0909341SAndroid Build Coastguard Worker         fclose(md5->f);
279*c0909341SAndroid Build Coastguard Worker }
280*c0909341SAndroid Build Coastguard Worker 
md5_verify(MD5Context * const md5,const char * md5_str)281*c0909341SAndroid Build Coastguard Worker static int md5_verify(MD5Context *const md5, const char *md5_str) {
282*c0909341SAndroid Build Coastguard Worker     md5_finish(md5);
283*c0909341SAndroid Build Coastguard Worker 
284*c0909341SAndroid Build Coastguard Worker     if (strlen(md5_str) < 32)
285*c0909341SAndroid Build Coastguard Worker         return -1;
286*c0909341SAndroid Build Coastguard Worker 
287*c0909341SAndroid Build Coastguard Worker     uint32_t abcd[4] = { 0 };
288*c0909341SAndroid Build Coastguard Worker     char t[3] = { 0 };
289*c0909341SAndroid Build Coastguard Worker     for (int i = 0; i < 4; i++) {
290*c0909341SAndroid Build Coastguard Worker         for (int j = 0; j < 32; j += 8) {
291*c0909341SAndroid Build Coastguard Worker             char *ignore;
292*c0909341SAndroid Build Coastguard Worker             memcpy(t, md5_str, 2);
293*c0909341SAndroid Build Coastguard Worker             md5_str += 2;
294*c0909341SAndroid Build Coastguard Worker             abcd[i] |= (uint32_t) strtoul(t, &ignore, 16) << j;
295*c0909341SAndroid Build Coastguard Worker         }
296*c0909341SAndroid Build Coastguard Worker     }
297*c0909341SAndroid Build Coastguard Worker 
298*c0909341SAndroid Build Coastguard Worker #if ENDIANNESS_BIG
299*c0909341SAndroid Build Coastguard Worker     free(md5->bswap);
300*c0909341SAndroid Build Coastguard Worker     md5->bswap_w = 0;
301*c0909341SAndroid Build Coastguard Worker #endif
302*c0909341SAndroid Build Coastguard Worker 
303*c0909341SAndroid Build Coastguard Worker     return !!memcmp(abcd, md5->abcd, sizeof(abcd));
304*c0909341SAndroid Build Coastguard Worker }
305*c0909341SAndroid Build Coastguard Worker 
306*c0909341SAndroid Build Coastguard Worker const Muxer md5_muxer = {
307*c0909341SAndroid Build Coastguard Worker     .priv_data_size = sizeof(MD5Context),
308*c0909341SAndroid Build Coastguard Worker     .name = "md5",
309*c0909341SAndroid Build Coastguard Worker     .extension = "md5",
310*c0909341SAndroid Build Coastguard Worker     .write_header = md5_open,
311*c0909341SAndroid Build Coastguard Worker     .write_picture = md5_write,
312*c0909341SAndroid Build Coastguard Worker     .write_trailer = md5_close,
313*c0909341SAndroid Build Coastguard Worker     .verify = md5_verify,
314*c0909341SAndroid Build Coastguard Worker };
315