void mdfour(unsigned char *out, const unsigned char *in, int n){ struct mdfour md; mdfour_begin(&md); mdfour_update(&md, in, n); mdfour_result(&md, out); }
static void CalcHash( void **list ) { struct mdfour md; file_info_t *info; size_t len; mdfour_begin( &md ); while( *list ) { info = *list++; len = sizeof( *info ) + strlen( info->name ) - 1; mdfour_update( &md, ( uint8_t * )info, len ); } mdfour_result( &md, m_demos.hash ); }
int get_checksum2(char *buf,int len,char *sum) { int i; static char *buf1; static int len1; struct mdfour m; char tsum[MD4_LENGTH]; if (len > len1) { if (buf1) free(buf1); buf1 = (char *)malloc(len+4); len1 = len; errno = ENOMEM; if (!buf1) return -1; } mdfour_begin(&m); memcpy(buf1,buf,len); if (checksum_seed) { SIVAL(buf1,len,checksum_seed); len += 4; } for(i = 0; i + CSUM_CHUNK <= len; i += CSUM_CHUNK) { mdfour_update(&m, (uchar *)(buf1+i), CSUM_CHUNK); } if (len - i > 0) { mdfour_update(&m, (uchar *)(buf1+i), (len-i)); } mdfour_result(&m, (uchar *)tsum); memcpy(sum, tsum, SUM_LENGTH); return 0; }
void gl_Mod_MakeAliasModelDisplayLists (model_t *m, aliashdr_t *hdr, void *_m, int _s, int extra) { dstring_t *cache, *fullpath; unsigned char model_digest[MDFOUR_DIGEST_BYTES]; unsigned char mesh_digest[MDFOUR_DIGEST_BYTES]; int i, j; int *cmds; QFile *f; qboolean remesh = true; qboolean do_cache = false; aliasmodel = m; paliashdr = hdr; cache = dstring_new (); fullpath = dstring_new (); if (!gl_alias_render_tri->int_val) { if (gl_mesh_cache->int_val && gl_mesh_cache->int_val <= paliashdr->mdl.numtris) { do_cache = true; mdfour (model_digest, (unsigned char *) _m, _s); // look for a cached version dstring_copystr (cache, "glquake/"); dstring_appendstr (cache, m->name); QFS_StripExtension (m->name + strlen ("progs/"), cache->str + strlen ("glquake/")); dstring_appendstr (cache, ".qfms"); QFS_FOpenFile (cache->str, &f); if (f) { unsigned char d1[MDFOUR_DIGEST_BYTES]; unsigned char d2[MDFOUR_DIGEST_BYTES]; struct mdfour md; int len, vers; int nc = 0, no = 0; int *c = 0, *vo = 0; memset (d1, 0, sizeof (d1)); memset (d2, 0, sizeof (d2)); Qread (f, &vers, sizeof (int)); Qread (f, &len, sizeof (int)); Qread (f, &nc, sizeof (int)); Qread (f, &no, sizeof (int)); if (vers == 1 && (nc + no) == len) { c = malloc (((nc + 1023) & ~1023) * sizeof (c[0])); vo = malloc (((no + 1023) & ~1023) * sizeof (vo[0])); if (!c || !vo) Sys_Error ("gl_mesh.c: out of memory"); Qread (f, c, nc * sizeof (c[0])); Qread (f, vo, no * sizeof (vo[0])); Qread (f, d1, MDFOUR_DIGEST_BYTES); Qread (f, d2, MDFOUR_DIGEST_BYTES); Qclose (f); mdfour_begin (&md); mdfour_update (&md, (unsigned char *) &vers, sizeof(int)); mdfour_update (&md, (unsigned char *) &len, sizeof(int)); mdfour_update (&md, (unsigned char *) &nc, sizeof(int)); mdfour_update (&md, (unsigned char *) &no, sizeof(int)); mdfour_update (&md, (unsigned char *) c, nc * sizeof (c[0])); mdfour_update (&md, (unsigned char *) vo, no * sizeof (vo[0])); mdfour_update (&md, d1, MDFOUR_DIGEST_BYTES); mdfour_result (&md, mesh_digest); if (memcmp (d2, mesh_digest, MDFOUR_DIGEST_BYTES) == 0 && memcmp (d1, model_digest, MDFOUR_DIGEST_BYTES) == 0) { remesh = false; numcommands = nc; numorder = no; if (numcommands > commands_size) { if (commands) free (commands); commands_size = (numcommands + 1023) & ~1023; commands = c; } else { memcpy (commands, c, numcommands * sizeof (c[0])); free(c); } if (numorder > vertexorder_size) { if (vertexorder) free (vertexorder); vertexorder_size = (numorder + 1023) & ~1023; vertexorder = vo; } else { memcpy (vertexorder, vo, numorder * sizeof (vo[0])); free (vo); } } } } } if (remesh) { // build it from scratch Sys_MaskPrintf (SYS_DEV, "meshing %s...\n", m->name); BuildTris (); // trifans or lists if (do_cache) { // save out the cached version dsprintf (fullpath, "%s/%s", qfs_gamedir->dir.def, cache->str); f = QFS_WOpen (fullpath->str, 9); if (f) { struct mdfour md; int vers = 1; int len = numcommands + numorder; mdfour_begin (&md); mdfour_update (&md, (unsigned char *) &vers, sizeof (int)); mdfour_update (&md, (unsigned char *) &len, sizeof (int)); mdfour_update (&md, (unsigned char *) &numcommands, sizeof (int)); mdfour_update (&md, (unsigned char *) &numorder, sizeof (int)); mdfour_update (&md, (unsigned char *) commands, numcommands * sizeof (commands[0])); mdfour_update (&md, (unsigned char *) vertexorder, numorder * sizeof (vertexorder[0])); mdfour_update (&md, model_digest, MDFOUR_DIGEST_BYTES); mdfour_result (&md, mesh_digest); Qwrite (f, &vers, sizeof (int)); Qwrite (f, &len, sizeof (int)); Qwrite (f, &numcommands, sizeof (int)); Qwrite (f, &numorder, sizeof (int)); Qwrite (f, commands, numcommands * sizeof (commands[0])); Qwrite (f, vertexorder, numorder * sizeof (vertexorder[0])); Qwrite (f, model_digest, MDFOUR_DIGEST_BYTES); Qwrite (f, mesh_digest, MDFOUR_DIGEST_BYTES); Qclose (f); } } } // save the data out paliashdr->poseverts = numorder; cmds = Hunk_Alloc (numcommands * sizeof (int)); paliashdr->commands = (byte *) cmds - (byte *) paliashdr; memcpy (cmds, commands, numcommands * sizeof (int)); } else { tex_coord_t *tex_coord; numorder = 0; for (i=0; i < pheader->mdl.numtris; i++) { add_vertex(triangles[i].vertindex[0]); add_vertex(triangles[i].vertindex[1]); add_vertex(triangles[i].vertindex[2]); } paliashdr->poseverts = numorder; tex_coord = Hunk_Alloc (numorder * sizeof(tex_coord_t)); paliashdr->tex_coord = (byte *) tex_coord - (byte *) paliashdr; for (i=0; i < numorder; i++) { float s, t; int k; k = vertexorder[i]; s = stverts[k].s; t = stverts[k].t; if (!triangles[i/3].facesfront && stverts[k].onseam) s += pheader->mdl.skinwidth / 2; // on back side s = (s + 0.5) / pheader->mdl.skinwidth; t = (t + 0.5) / pheader->mdl.skinheight; tex_coord[i].st[0] = s; tex_coord[i].st[1] = t; } } if (extra) { trivertx16_t *verts; verts = Hunk_Alloc (paliashdr->numposes * paliashdr->poseverts * sizeof (trivertx16_t)); paliashdr->posedata = (byte *) verts - (byte *) paliashdr; for (i = 0; i < paliashdr->numposes; i++) { trivertx_t *pv = poseverts[i]; for (j = 0; j < numorder; j++) { trivertx16_t v; // convert MD16's split coordinates into something a little // saner. The first chunk of vertices is fully compatible with // IDPO alias models (even the scale). The second chunk is the // fractional bits of the vertex, giving 8.8. However, it's // easier for us to multiply everything by 256 and adjust the // model scale appropriately VectorMultAdd (pv[vertexorder[j] + hdr->mdl.numverts].v, 256, pv[vertexorder[j]].v, v.v); v.lightnormalindex = poseverts[i][vertexorder[j]].lightnormalindex; *verts++ = v; } } } else { trivertx_t *verts; verts = Hunk_Alloc (paliashdr->numposes * paliashdr->poseverts * sizeof (trivertx_t)); paliashdr->posedata = (byte *) verts - (byte *) paliashdr; for (i = 0; i < paliashdr->numposes; i++) { for (j = 0; j < numorder; j++) *verts++ = poseverts[i][vertexorder[j]]; } } dstring_delete (cache); dstring_delete (fullpath); }
void hash_result_as_bytes(struct hash *hash, unsigned char *out) { mdfour_result(&hash->md, out); }
/* return the hash result as 16 binary bytes */ void hash_result_as_bytes(struct mdfour *md, unsigned char *out) { hash_buffer(md, NULL, 0); mdfour_result(md, out); }