789 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			789 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								#define HL_NAME(n) fmt_##n
							 | 
						||
| 
								 | 
							
								//#include <png.h>
							 | 
						||
| 
								 | 
							
								#include <hl.h>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#if defined(HL_CONSOLE) && !defined(HL_XBO)
							 | 
						||
| 
								 | 
							
								//extern bool sys_jpg_decode( vbyte *data, int dataLen, vbyte *out, int width, int height, int stride, int format, int flags );
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								//#	include <turbojpeg.h>
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <zlib.h>
							 | 
						||
| 
								 | 
							
								//#include <vorbis/vorbisfile.h>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//#define MINIMP3_IMPLEMENTATION
							 | 
						||
| 
								 | 
							
								//#define MINIMP3_FLOAT_OUTPUT
							 | 
						||
| 
								 | 
							
								//#include <minimp3.h>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* ------------------------------------------------- IMG --------------------------------------------------- */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								typedef struct {
							 | 
						||
| 
								 | 
							
									unsigned char a,r,g,b;
							 | 
						||
| 
								 | 
							
								} pixel;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*HL_PRIM bool HL_NAME(jpg_decode)( vbyte *data, int dataLen, vbyte *out, int width, int height, int stride, int format, int flags ) {
							 | 
						||
| 
								 | 
							
								#if defined(HL_CONSOLE) && !defined(HL_XBO)
							 | 
						||
| 
								 | 
							
									hl_blocking(true);
							 | 
						||
| 
								 | 
							
									bool b = sys_jpg_decode(data, dataLen, out, width, height, stride, format, flags);
							 | 
						||
| 
								 | 
							
									hl_blocking(false);
							 | 
						||
| 
								 | 
							
									return b;
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
									hl_blocking(true);
							 | 
						||
| 
								 | 
							
									tjhandle h = tjInitDecompress();
							 | 
						||
| 
								 | 
							
									int result;
							 | 
						||
| 
								 | 
							
									result = tjDecompress2(h,data,dataLen,out,width,stride,height,format,(flags & 1 ? TJFLAG_BOTTOMUP : 0));
							 | 
						||
| 
								 | 
							
									tjDestroy(h);
							 | 
						||
| 
								 | 
							
									hl_blocking(false);
							 | 
						||
| 
								 | 
							
									return result == 0;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								HL_PRIM bool HL_NAME(png_decode)( vbyte *data, int dataLen, vbyte *out, int width, int height, int stride, int format, int flags ) {
							 | 
						||
| 
								 | 
							
								#	ifdef PNG_IMAGE_VERSION
							 | 
						||
| 
								 | 
							
									png_image img;
							 | 
						||
| 
								 | 
							
									hl_blocking(true);
							 | 
						||
| 
								 | 
							
									memset(&img, 0, sizeof(img));
							 | 
						||
| 
								 | 
							
									img.version = PNG_IMAGE_VERSION;
							 | 
						||
| 
								 | 
							
									if( png_image_begin_read_from_memory(&img,data,dataLen) == 0 ) {
							 | 
						||
| 
								 | 
							
										hl_blocking(false);
							 | 
						||
| 
								 | 
							
										png_image_free(&img);
							 | 
						||
| 
								 | 
							
										return false;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									switch( format ) {
							 | 
						||
| 
								 | 
							
									case 0:
							 | 
						||
| 
								 | 
							
										img.format = PNG_FORMAT_RGB;
							 | 
						||
| 
								 | 
							
										break;
							 | 
						||
| 
								 | 
							
									case 1:
							 | 
						||
| 
								 | 
							
										img.format = PNG_FORMAT_BGR;
							 | 
						||
| 
								 | 
							
										break;
							 | 
						||
| 
								 | 
							
									case 7:
							 | 
						||
| 
								 | 
							
										img.format = PNG_FORMAT_RGBA;
							 | 
						||
| 
								 | 
							
										break;
							 | 
						||
| 
								 | 
							
									case 8:
							 | 
						||
| 
								 | 
							
										img.format = PNG_FORMAT_BGRA;
							 | 
						||
| 
								 | 
							
										break;
							 | 
						||
| 
								 | 
							
									case 9:
							 | 
						||
| 
								 | 
							
										img.format = PNG_FORMAT_ABGR;
							 | 
						||
| 
								 | 
							
										break;
							 | 
						||
| 
								 | 
							
									case 10:
							 | 
						||
| 
								 | 
							
										img.format = PNG_FORMAT_ARGB;
							 | 
						||
| 
								 | 
							
										break;
							 | 
						||
| 
								 | 
							
									case 12:
							 | 
						||
| 
								 | 
							
										img.format = PNG_FORMAT_LINEAR_Y;
							 | 
						||
| 
								 | 
							
										break;
							 | 
						||
| 
								 | 
							
									case 13:
							 | 
						||
| 
								 | 
							
										img.format = PNG_FORMAT_LINEAR_RGB;
							 | 
						||
| 
								 | 
							
										break;
							 | 
						||
| 
								 | 
							
									case 14:
							 | 
						||
| 
								 | 
							
										img.format = PNG_FORMAT_LINEAR_RGB_ALPHA;
							 | 
						||
| 
								 | 
							
										break;
							 | 
						||
| 
								 | 
							
									case 15:
							 | 
						||
| 
								 | 
							
										img.format = PNG_FORMAT_LINEAR_Y_ALPHA;
							 | 
						||
| 
								 | 
							
										break;
							 | 
						||
| 
								 | 
							
									default:
							 | 
						||
| 
								 | 
							
										hl_blocking(false);
							 | 
						||
| 
								 | 
							
										png_image_free(&img);
							 | 
						||
| 
								 | 
							
										hl_error("Unsupported format");
							 | 
						||
| 
								 | 
							
										break;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if( img.width != width || img.height != height ) {
							 | 
						||
| 
								 | 
							
										hl_blocking(false);
							 | 
						||
| 
								 | 
							
										png_image_free(&img);
							 | 
						||
| 
								 | 
							
										return false;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									if( png_image_finish_read(&img,NULL,out,stride * (flags & 1 ? -1 : 1),NULL) == 0 ) {
							 | 
						||
| 
								 | 
							
										hl_blocking(false);
							 | 
						||
| 
								 | 
							
										png_image_free(&img);
							 | 
						||
| 
								 | 
							
										return false;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									hl_blocking(false);
							 | 
						||
| 
								 | 
							
									png_image_free(&img);
							 | 
						||
| 
								 | 
							
								#	else
							 | 
						||
| 
								 | 
							
									hl_error("PNG support is missing for this libPNG version");
							 | 
						||
| 
								 | 
							
								#	endif
							 | 
						||
| 
								 | 
							
									return true;
							 | 
						||
| 
								 | 
							
								}*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								HL_PRIM void HL_NAME(img_scale)( vbyte *out, int outPos, int outStride, int outWidth, int outHeight, vbyte *in, int inPos, int inStride, int inWidth, int inHeight, int flags ) {
							 | 
						||
| 
								 | 
							
									int x, y;
							 | 
						||
| 
								 | 
							
									float scaleX = outWidth <= 1 ? 0.0f : (float)((inWidth - 1.001f) / (outWidth - 1));
							 | 
						||
| 
								 | 
							
									float scaleY = outHeight <= 1 ? 0.0f : (float)((inHeight - 1.001f) / (outHeight - 1));
							 | 
						||
| 
								 | 
							
									out += outPos;
							 | 
						||
| 
								 | 
							
									in += inPos;
							 | 
						||
| 
								 | 
							
									hl_blocking(true);
							 | 
						||
| 
								 | 
							
									for(y=0;y<outHeight;y++) {
							 | 
						||
| 
								 | 
							
										for(x=0;x<outWidth;x++) {
							 | 
						||
| 
								 | 
							
											float fx = x * scaleX;
							 | 
						||
| 
								 | 
							
											float fy = y * scaleY;
							 | 
						||
| 
								 | 
							
											int ix = (int)fx;
							 | 
						||
| 
								 | 
							
											int iy = (int)fy;
							 | 
						||
| 
								 | 
							
											if( (flags & 1) == 0 ) {
							 | 
						||
| 
								 | 
							
												// nearest
							 | 
						||
| 
								 | 
							
												vbyte *rin = in + iy * inStride;
							 | 
						||
| 
								 | 
							
												*(pixel*)out = *(pixel*)(rin + (ix<<2));
							 | 
						||
| 
								 | 
							
												out += 4;
							 | 
						||
| 
								 | 
							
											} else {
							 | 
						||
| 
								 | 
							
												// bilinear
							 | 
						||
| 
								 | 
							
												float rx = fx - ix;
							 | 
						||
| 
								 | 
							
												float ry = fy - iy;
							 | 
						||
| 
								 | 
							
												float rx1 = 1.0f - rx;
							 | 
						||
| 
								 | 
							
												float ry1 = 1.0f - ry;
							 | 
						||
| 
								 | 
							
												int w1 = (int)(rx1 * ry1 * 256.0f);
							 | 
						||
| 
								 | 
							
												int w2 = (int)(rx * ry1 * 256.0f);
							 | 
						||
| 
								 | 
							
												int w3 = (int)(rx1 * ry * 256.0f);
							 | 
						||
| 
								 | 
							
												int w4 = (int)(rx * ry * 256.0f);
							 | 
						||
| 
								 | 
							
												vbyte *rin = in + iy * inStride;
							 | 
						||
| 
								 | 
							
												pixel p1 = *(pixel*)(rin + (ix<<2));
							 | 
						||
| 
								 | 
							
												pixel p2 = *(pixel*)(rin + ((ix + 1)<<2));
							 | 
						||
| 
								 | 
							
												pixel p3 = *(pixel*)(rin + inStride + (ix<<2));
							 | 
						||
| 
								 | 
							
												pixel p4 = *(pixel*)(rin + inStride + ((ix + 1)<<2));
							 | 
						||
| 
								 | 
							
												*out++ = (unsigned char)((p1.a * w1 + p2.a * w2 + p3.a * w3 + p4.a * w4 + 128)>>8);
							 | 
						||
| 
								 | 
							
												*out++ = (unsigned char)((p1.r * w1 + p2.r * w2 + p3.r * w3 + p4.r * w4 + 128)>>8);
							 | 
						||
| 
								 | 
							
												*out++ = (unsigned char)((p1.g * w1 + p2.g * w2 + p3.g * w3 + p4.g * w4 + 128)>>8);
							 | 
						||
| 
								 | 
							
												*out++ = (unsigned char)((p1.b * w1 + p2.b * w2 + p3.b * w3 + p4.b * w4 + 128)>>8);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										out += outStride - (outWidth << 2);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									hl_blocking(false);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								DEFINE_PRIM(_BOOL, jpg_decode, _BYTES _I32 _BYTES _I32 _I32 _I32 _I32 _I32);
							 | 
						||
| 
								 | 
							
								DEFINE_PRIM(_BOOL, png_decode, _BYTES _I32 _BYTES _I32 _I32 _I32 _I32 _I32);
							 | 
						||
| 
								 | 
							
								DEFINE_PRIM(_VOID, img_scale, _BYTES _I32 _I32 _I32 _I32 _BYTES _I32 _I32 _I32 _I32 _I32);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* ------------------------------------------------- ZLIB --------------------------------------------------- */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								typedef struct _fmt_zip fmt_zip;
							 | 
						||
| 
								 | 
							
								struct _fmt_zip {
							 | 
						||
| 
								 | 
							
									void (*finalize)( fmt_zip * );
							 | 
						||
| 
								 | 
							
									z_stream *z;
							 | 
						||
| 
								 | 
							
									int flush;
							 | 
						||
| 
								 | 
							
									bool inflate;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void free_stream_inf( fmt_zip *v ) {
							 | 
						||
| 
								 | 
							
									if( v->inflate )
							 | 
						||
| 
								 | 
							
										inflateEnd(v->z); // no error
							 | 
						||
| 
								 | 
							
									else
							 | 
						||
| 
								 | 
							
										deflateEnd(v->z);
							 | 
						||
| 
								 | 
							
									free(v->z);
							 | 
						||
| 
								 | 
							
									v->z = NULL;
							 | 
						||
| 
								 | 
							
									v->finalize = NULL;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void zlib_error( z_stream *z, int err ) {
							 | 
						||
| 
								 | 
							
									hl_buffer *b = hl_alloc_buffer();
							 | 
						||
| 
								 | 
							
									vdynamic *d;
							 | 
						||
| 
								 | 
							
									hl_buffer_cstr(b, "ZLib Error : ");
							 | 
						||
| 
								 | 
							
									if( z && z->msg ) {
							 | 
						||
| 
								 | 
							
										hl_buffer_cstr(b,z->msg);
							 | 
						||
| 
								 | 
							
										hl_buffer_cstr(b," (");
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									d = hl_alloc_dynamic(&hlt_i32);
							 | 
						||
| 
								 | 
							
									d->v.i = err;
							 | 
						||
| 
								 | 
							
									hl_buffer_val(b,d);
							 | 
						||
| 
								 | 
							
									if( z && z->msg )
							 | 
						||
| 
								 | 
							
										hl_buffer_char(b,')');
							 | 
						||
| 
								 | 
							
									d = hl_alloc_dynamic(&hlt_bytes);
							 | 
						||
| 
								 | 
							
									d->v.ptr = hl_buffer_content(b,NULL);
							 | 
						||
| 
								 | 
							
									hl_throw(d);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								HL_PRIM fmt_zip *HL_NAME(inflate_init)( int wbits ) {
							 | 
						||
| 
								 | 
							
									z_stream *z;
							 | 
						||
| 
								 | 
							
									int err;
							 | 
						||
| 
								 | 
							
									fmt_zip *s;
							 | 
						||
| 
								 | 
							
									if( wbits == 0 )
							 | 
						||
| 
								 | 
							
										wbits = MAX_WBITS;
							 | 
						||
| 
								 | 
							
									z = (z_stream*)malloc(sizeof(z_stream));
							 | 
						||
| 
								 | 
							
									memset(z,0,sizeof(z_stream));
							 | 
						||
| 
								 | 
							
									if( (err = inflateInit2(z,wbits)) != Z_OK ) {
							 | 
						||
| 
								 | 
							
										free(z);
							 | 
						||
| 
								 | 
							
										zlib_error(NULL,err);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									s = (fmt_zip*)hl_gc_alloc_finalizer(sizeof(fmt_zip));
							 | 
						||
| 
								 | 
							
									s->finalize = free_stream_inf;
							 | 
						||
| 
								 | 
							
									s->flush = Z_NO_FLUSH;
							 | 
						||
| 
								 | 
							
									s->z = z;
							 | 
						||
| 
								 | 
							
									s->inflate = true;
							 | 
						||
| 
								 | 
							
									return s;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								HL_PRIM fmt_zip *HL_NAME(deflate_init)( int level ) {
							 | 
						||
| 
								 | 
							
									z_stream *z;
							 | 
						||
| 
								 | 
							
									int err;
							 | 
						||
| 
								 | 
							
									fmt_zip *s;
							 | 
						||
| 
								 | 
							
									z = (z_stream*)malloc(sizeof(z_stream));
							 | 
						||
| 
								 | 
							
									memset(z,0,sizeof(z_stream));
							 | 
						||
| 
								 | 
							
									if( (err = deflateInit(z,level)) != Z_OK ) {
							 | 
						||
| 
								 | 
							
										free(z);
							 | 
						||
| 
								 | 
							
										zlib_error(NULL,err);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									s = (fmt_zip*)hl_gc_alloc_finalizer(sizeof(fmt_zip));
							 | 
						||
| 
								 | 
							
									s->finalize = free_stream_inf;
							 | 
						||
| 
								 | 
							
									s->flush = Z_NO_FLUSH;
							 | 
						||
| 
								 | 
							
									s->z = z;
							 | 
						||
| 
								 | 
							
									s->inflate = false;
							 | 
						||
| 
								 | 
							
									return s;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								HL_PRIM void HL_NAME(zip_end)( fmt_zip *z ) {
							 | 
						||
| 
								 | 
							
									free_stream_inf(z);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								HL_PRIM void HL_NAME(zip_flush_mode)( fmt_zip *z, int flush ) {
							 | 
						||
| 
								 | 
							
									switch( flush ) {
							 | 
						||
| 
								 | 
							
									case 0:
							 | 
						||
| 
								 | 
							
										z->flush = Z_NO_FLUSH;
							 | 
						||
| 
								 | 
							
										break;
							 | 
						||
| 
								 | 
							
									case 1:
							 | 
						||
| 
								 | 
							
										z->flush = Z_SYNC_FLUSH;
							 | 
						||
| 
								 | 
							
										break;
							 | 
						||
| 
								 | 
							
									case 2:
							 | 
						||
| 
								 | 
							
										z->flush = Z_FULL_FLUSH;
							 | 
						||
| 
								 | 
							
										break;
							 | 
						||
| 
								 | 
							
									case 3:
							 | 
						||
| 
								 | 
							
										z->flush = Z_FINISH;
							 | 
						||
| 
								 | 
							
										break;
							 | 
						||
| 
								 | 
							
									case 4:
							 | 
						||
| 
								 | 
							
										z->flush = Z_BLOCK;
							 | 
						||
| 
								 | 
							
										break;
							 | 
						||
| 
								 | 
							
									default:
							 | 
						||
| 
								 | 
							
										hl_error("Invalid flush mode %d",flush);
							 | 
						||
| 
								 | 
							
										break;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								HL_PRIM bool HL_NAME(inflate_buffer)( fmt_zip *zip, vbyte *src, int srcpos, int srclen, vbyte *dst, int dstpos, int dstlen, int *read, int *write ) {
							 | 
						||
| 
								 | 
							
									int slen, dlen, err;
							 | 
						||
| 
								 | 
							
									z_stream *z = zip->z;
							 | 
						||
| 
								 | 
							
									slen = srclen - srcpos;
							 | 
						||
| 
								 | 
							
									dlen = dstlen - dstpos;
							 | 
						||
| 
								 | 
							
									if( srcpos < 0 || dstpos < 0 || slen < 0 || dlen < 0 )
							 | 
						||
| 
								 | 
							
										hl_error("Out of range");
							 | 
						||
| 
								 | 
							
									hl_blocking(true);
							 | 
						||
| 
								 | 
							
									z->next_in = (Bytef*)(src + srcpos);
							 | 
						||
| 
								 | 
							
									z->next_out = (Bytef*)(dst + dstpos);
							 | 
						||
| 
								 | 
							
									z->avail_in = slen;
							 | 
						||
| 
								 | 
							
									z->avail_out = dlen;
							 | 
						||
| 
								 | 
							
									if( (err = inflate(z,zip->flush)) < 0 ) {
							 | 
						||
| 
								 | 
							
										hl_blocking(false);
							 | 
						||
| 
								 | 
							
										zlib_error(z,err);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									z->next_in = NULL;
							 | 
						||
| 
								 | 
							
									z->next_out = NULL;
							 | 
						||
| 
								 | 
							
									*read = slen - z->avail_in;
							 | 
						||
| 
								 | 
							
									*write = dlen - z->avail_out;
							 | 
						||
| 
								 | 
							
									hl_blocking(false);
							 | 
						||
| 
								 | 
							
									return err == Z_STREAM_END;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								HL_PRIM bool HL_NAME(deflate_buffer)( fmt_zip *zip, vbyte *src, int srcpos, int srclen, vbyte *dst, int dstpos, int dstlen, int *read, int *write ) {
							 | 
						||
| 
								 | 
							
									int slen, dlen, err;
							 | 
						||
| 
								 | 
							
									z_stream *z = zip->z;
							 | 
						||
| 
								 | 
							
									slen = srclen - srcpos;
							 | 
						||
| 
								 | 
							
									dlen = dstlen - dstpos;
							 | 
						||
| 
								 | 
							
									if( srcpos < 0 || dstpos < 0 || slen < 0 || dlen < 0 )
							 | 
						||
| 
								 | 
							
										hl_error("Out of range");
							 | 
						||
| 
								 | 
							
									hl_blocking(true);
							 | 
						||
| 
								 | 
							
									z->next_in = (Bytef*)(src + srcpos);
							 | 
						||
| 
								 | 
							
									z->next_out = (Bytef*)(dst + dstpos);
							 | 
						||
| 
								 | 
							
									z->avail_in = slen;
							 | 
						||
| 
								 | 
							
									z->avail_out = dlen;
							 | 
						||
| 
								 | 
							
									if( (err = deflate(z,zip->flush)) < 0 ) {
							 | 
						||
| 
								 | 
							
										hl_blocking(false);
							 | 
						||
| 
								 | 
							
										zlib_error(z,err);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									z->next_in = NULL;
							 | 
						||
| 
								 | 
							
									z->next_out = NULL;
							 | 
						||
| 
								 | 
							
									*read = slen - z->avail_in;
							 | 
						||
| 
								 | 
							
									*write = dlen - z->avail_out;
							 | 
						||
| 
								 | 
							
									hl_blocking(false);
							 | 
						||
| 
								 | 
							
									return err == Z_STREAM_END;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								HL_PRIM int HL_NAME(deflate_bound)( fmt_zip *zip, int size ) {
							 | 
						||
| 
								 | 
							
									return deflateBound(zip->z,size);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define _ZIP _ABSTRACT(fmt_zip)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								DEFINE_PRIM(_ZIP, inflate_init, _I32);
							 | 
						||
| 
								 | 
							
								DEFINE_PRIM(_ZIP, deflate_init, _I32);
							 | 
						||
| 
								 | 
							
								DEFINE_PRIM(_I32, deflate_bound, _ZIP _I32);
							 | 
						||
| 
								 | 
							
								DEFINE_PRIM(_VOID, zip_end, _ZIP);
							 | 
						||
| 
								 | 
							
								DEFINE_PRIM(_VOID, zip_flush_mode, _ZIP _I32);
							 | 
						||
| 
								 | 
							
								DEFINE_PRIM(_BOOL, inflate_buffer, _ZIP _BYTES _I32 _I32 _BYTES _I32 _I32 _REF(_I32) _REF(_I32));
							 | 
						||
| 
								 | 
							
								DEFINE_PRIM(_BOOL, deflate_buffer, _ZIP _BYTES _I32 _I32 _BYTES _I32 _I32 _REF(_I32) _REF(_I32));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* ----------------------------------------------- SOUND : OGG ------------------------------------------------ */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*typedef struct _fmt_ogg fmt_ogg;
							 | 
						||
| 
								 | 
							
								struct _fmt_ogg {
							 | 
						||
| 
								 | 
							
									void (*finalize)( fmt_ogg * );
							 | 
						||
| 
								 | 
							
									OggVorbis_File f;
							 | 
						||
| 
								 | 
							
									char *bytes;
							 | 
						||
| 
								 | 
							
									int pos;
							 | 
						||
| 
								 | 
							
									int size;
							 | 
						||
| 
								 | 
							
									int section;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void ogg_finalize( fmt_ogg *o ) {
							 | 
						||
| 
								 | 
							
									ov_clear(&o->f);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static size_t ogg_memread( void *ptr, int size, int count, fmt_ogg *o ) {
							 | 
						||
| 
								 | 
							
									int len = size * count;
							 | 
						||
| 
								 | 
							
									if( o->pos + len > o->size )
							 | 
						||
| 
								 | 
							
										len = o->size - o->pos;
							 | 
						||
| 
								 | 
							
									memcpy(ptr, o->bytes + o->pos, len);
							 | 
						||
| 
								 | 
							
									o->pos += len;
							 | 
						||
| 
								 | 
							
									return len;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static int ogg_memseek( fmt_ogg *o, ogg_int64_t _offset, int mode ) {
							 | 
						||
| 
								 | 
							
									int offset = (int)_offset;
							 | 
						||
| 
								 | 
							
									switch( mode ) {
							 | 
						||
| 
								 | 
							
									case SEEK_SET:
							 | 
						||
| 
								 | 
							
										if( offset < 0 || offset > o->size ) return 1;
							 | 
						||
| 
								 | 
							
										o->pos = offset;
							 | 
						||
| 
								 | 
							
										break;
							 | 
						||
| 
								 | 
							
									case SEEK_CUR:
							 | 
						||
| 
								 | 
							
										if( o->pos + offset < 0 || o->pos + offset > o->size ) return 1;
							 | 
						||
| 
								 | 
							
										o->pos += offset;
							 | 
						||
| 
								 | 
							
										break;
							 | 
						||
| 
								 | 
							
									case SEEK_END:
							 | 
						||
| 
								 | 
							
										if( offset < 0 || offset > o->size ) return 1;
							 | 
						||
| 
								 | 
							
										o->pos = o->size - offset;
							 | 
						||
| 
								 | 
							
										break;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return 0;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static long ogg_memtell( fmt_ogg *o ) {
							 | 
						||
| 
								 | 
							
									return o->pos;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static ov_callbacks OV_CALLBACKS_MEMORY = {
							 | 
						||
| 
								 | 
							
								  (size_t (*)(void *, size_t, size_t, void *))  ogg_memread,
							 | 
						||
| 
								 | 
							
								  (int (*)(void *, ogg_int64_t, int))           ogg_memseek,
							 | 
						||
| 
								 | 
							
								  (int (*)(void *))                             NULL,
							 | 
						||
| 
								 | 
							
								  (long (*)(void *))                            ogg_memtell
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								HL_PRIM fmt_ogg *HL_NAME(ogg_open)( char *bytes, int size ) {
							 | 
						||
| 
								 | 
							
									fmt_ogg *o = (fmt_ogg*)hl_gc_alloc_finalizer(sizeof(fmt_ogg));
							 | 
						||
| 
								 | 
							
									o->finalize = NULL;
							 | 
						||
| 
								 | 
							
									o->bytes = bytes;
							 | 
						||
| 
								 | 
							
									o->size = size;
							 | 
						||
| 
								 | 
							
									o->pos = 0;
							 | 
						||
| 
								 | 
							
									if( ov_open_callbacks(o,&o->f,NULL,0,OV_CALLBACKS_MEMORY) != 0 )
							 | 
						||
| 
								 | 
							
										return NULL;
							 | 
						||
| 
								 | 
							
									o->finalize = ogg_finalize;
							 | 
						||
| 
								 | 
							
									return o;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								HL_PRIM void HL_NAME(ogg_info)( fmt_ogg *o, int *bitrate, int *freq, int *samples, int *channels ) {
							 | 
						||
| 
								 | 
							
									vorbis_info *i = ov_info(&o->f,-1);
							 | 
						||
| 
								 | 
							
									*bitrate = i->bitrate_nominal;
							 | 
						||
| 
								 | 
							
									*freq = i->rate;
							 | 
						||
| 
								 | 
							
									*channels = i->channels;
							 | 
						||
| 
								 | 
							
									*samples = (int)ov_pcm_total(&o->f, -1);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								HL_PRIM int HL_NAME(ogg_tell)( fmt_ogg *o ) {
							 | 
						||
| 
								 | 
							
									return (int)ov_pcm_tell(&o->f); // overflow at 12 hours @48 Khz
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								HL_PRIM bool HL_NAME(ogg_seek)( fmt_ogg *o, int sample ) {
							 | 
						||
| 
								 | 
							
									return ov_pcm_seek(&o->f,sample) == 0;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define OGGFMT_I8			1
							 | 
						||
| 
								 | 
							
								#define OGGFMT_I16			2
							 | 
						||
| 
								 | 
							
								//#define OGGFMT_F32		3
							 | 
						||
| 
								 | 
							
								#define OGGFMT_BIGENDIAN	128
							 | 
						||
| 
								 | 
							
								#define OGGFMT_UNSIGNED		256
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								HL_PRIM int HL_NAME(ogg_read)( fmt_ogg *o, char *output, int size, int format ) {
							 | 
						||
| 
								 | 
							
									int ret = -1;
							 | 
						||
| 
								 | 
							
									hl_blocking(true);
							 | 
						||
| 
								 | 
							
									switch( format&127 ) {
							 | 
						||
| 
								 | 
							
									case OGGFMT_I8:
							 | 
						||
| 
								 | 
							
									case OGGFMT_I16:
							 | 
						||
| 
								 | 
							
										ret = ov_read(&o->f, output, size, (format & OGGFMT_BIGENDIAN) != 0, format&3, (format & OGGFMT_UNSIGNED) == 0, &o->section);
							 | 
						||
| 
								 | 
							
										break;
							 | 
						||
| 
								 | 
							
								//	case OGGFMT_F32:
							 | 
						||
| 
								 | 
							
								//		-- this decodes separates channels instead of mixed single buffer one
							 | 
						||
| 
								 | 
							
								//		return ov_read_float(&o->f, output, size, (format & OGGFMT_BIGENDIAN) != 0, format&3, (format & OGGFMT_UNSIGNED) == 0, &o->section);
							 | 
						||
| 
								 | 
							
									default:
							 | 
						||
| 
								 | 
							
										break;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									hl_blocking(false);
							 | 
						||
| 
								 | 
							
									return ret;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define _OGG _ABSTRACT(fmt_ogg)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								DEFINE_PRIM(_OGG, ogg_open, _BYTES _I32);
							 | 
						||
| 
								 | 
							
								DEFINE_PRIM(_VOID, ogg_info, _OGG _REF(_I32) _REF(_I32) _REF(_I32) _REF(_I32));
							 | 
						||
| 
								 | 
							
								DEFINE_PRIM(_I32, ogg_tell, _OGG);
							 | 
						||
| 
								 | 
							
								DEFINE_PRIM(_BOOL, ogg_seek, _OGG _I32);
							 | 
						||
| 
								 | 
							
								DEFINE_PRIM(_I32, ogg_read, _OGG _BYTES _I32 _I32);*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* ----------------------------------------------- SOUND : MP3 ------------------------------------------------ */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*typedef struct _fmt_mp3 fmt_mp3;
							 | 
						||
| 
								 | 
							
								struct _fmt_mp3 {
							 | 
						||
| 
								 | 
							
									mp3dec_t dec;
							 | 
						||
| 
								 | 
							
									mp3dec_frame_info_t info;
							 | 
						||
| 
								 | 
							
									mp3d_sample_t pcm[MINIMP3_MAX_SAMPLES_PER_FRAME];
							 | 
						||
| 
								 | 
							
								};*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Allocate MP3 reader.
							 | 
						||
| 
								 | 
							
								/*HL_PRIM fmt_mp3 *HL_NAME(mp3_open)() {
							 | 
						||
| 
								 | 
							
									fmt_mp3 *o = (fmt_mp3*)hl_gc_alloc_noptr(sizeof(fmt_mp3));
							 | 
						||
| 
								 | 
							
									mp3dec_init(&o->dec);
							 | 
						||
| 
								 | 
							
									return o;
							 | 
						||
| 
								 | 
							
								}*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
									Retreive last decoded frame information.
							 | 
						||
| 
								 | 
							
									@param bitrate_kbps Bitrate of the frame
							 | 
						||
| 
								 | 
							
									@param channels Total amount of channels in the frame.
							 | 
						||
| 
								 | 
							
									@param frame_bytes The size of the frame in the input stream,
							 | 
						||
| 
								 | 
							
									@param hz
							 | 
						||
| 
								 | 
							
									@param layer Mpeg Layer index (usually 3).
							 | 
						||
| 
								 | 
							
								**/
							 | 
						||
| 
								 | 
							
								/*HL_PRIM void HL_NAME(mp3_frame_info)(fmt_mp3 *o, int *bitrate_kbps, int *channels, int *frame_bytes, int *hz, int *layer) {
							 | 
						||
| 
								 | 
							
									*bitrate_kbps = o->info.bitrate_kbps;
							 | 
						||
| 
								 | 
							
									*channels = o->info.channels;
							 | 
						||
| 
								 | 
							
									*frame_bytes = o->info.frame_bytes;
							 | 
						||
| 
								 | 
							
									*hz = o->info.hz;
							 | 
						||
| 
								 | 
							
									*layer = o->info.layer;
							 | 
						||
| 
								 | 
							
								}*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
									Decodes a single frame from input stream and writes result to output.
							 | 
						||
| 
								 | 
							
									Decoded samples are in Float32 format. Output bytes should contain enough space to fit entire frame in.
							 | 
						||
| 
								 | 
							
									To calculate required output size, follow next formula: `samples * channels * 4`.
							 | 
						||
| 
								 | 
							
									For Layer 1, amount of frames is 384, MPEG 2 Layer 2 is 576 and 1152 otherwise. Using 1152 samples is the safest.
							 | 
						||
| 
								 | 
							
									@param o Allocated MP3 reader.
							 | 
						||
| 
								 | 
							
									@param bytes Input stream.
							 | 
						||
| 
								 | 
							
									@param size Input stream size.
							 | 
						||
| 
								 | 
							
									@param position Input stream offset.
							 | 
						||
| 
								 | 
							
									@param output Output stream.
							 | 
						||
| 
								 | 
							
									@param outputSize Output stream size.
							 | 
						||
| 
								 | 
							
									@param offset Output stream write offset.
							 | 
						||
| 
								 | 
							
									@returns 0 if no MP3 data was found (end of stream/invalid data), -1 if either input buffer position invalid or output size is insufficent.
							 | 
						||
| 
								 | 
							
										Amount of decoded samples otherwise.
							 | 
						||
| 
								 | 
							
								**/
							 | 
						||
| 
								 | 
							
								/*HL_PRIM int HL_NAME(mp3_decode_frame)( fmt_mp3 *o, char *bytes, int size, int position, char *output, int outputSize, int offset ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// Out of mp3 file bounds.
							 | 
						||
| 
								 | 
							
									if ( position < 0 || size <= position )
							 | 
						||
| 
								 | 
							
										return -1;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									int samples = 0;
							 | 
						||
| 
								 | 
							
									hl_blocking(true);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									do {
							 | 
						||
| 
								 | 
							
										samples = mp3dec_decode_frame(&o->dec, (unsigned char*)bytes + position, size - position, o->pcm, &o->info);
							 | 
						||
| 
								 | 
							
										// Try to read until found mp3 data or EOF.
							 | 
						||
| 
								 | 
							
										if ( samples != 0 || o->info.frame_bytes == 0 )
							 | 
						||
| 
								 | 
							
											break;
							 | 
						||
| 
								 | 
							
										position += o->info.frame_bytes;
							 | 
						||
| 
								 | 
							
									} while ( size > position );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// No or invalid MP3 data.
							 | 
						||
| 
								 | 
							
									if ( samples == 0 || o->info.frame_bytes == 0 ) {
							 | 
						||
| 
								 | 
							
										hl_blocking(false);
							 | 
						||
| 
								 | 
							
										return 0;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									int decodedSize = samples * o->info.channels * sizeof(mp3d_sample_t);
							 | 
						||
| 
								 | 
							
									// Insufficent output buffer size.
							 | 
						||
| 
								 | 
							
									if ( outputSize - offset < decodedSize ) {
							 | 
						||
| 
								 | 
							
										hl_blocking(false);
							 | 
						||
| 
								 | 
							
										return -1;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									memcpy( (void *)(output + offset), (void *)o->pcm, decodedSize );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									hl_blocking(false);
							 | 
						||
| 
								 | 
							
									return samples;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define _MP3 _ABSTRACT(fmt_mp3)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								DEFINE_PRIM(_MP3, mp3_open, _BYTES _I32);
							 | 
						||
| 
								 | 
							
								DEFINE_PRIM(_VOID, mp3_frame_info, _MP3 _REF(_I32) _REF(_I32) _REF(_I32) _REF(_I32) _REF(_I32))
							 | 
						||
| 
								 | 
							
								DEFINE_PRIM(_I32, mp3_decode_frame, _MP3 _BYTES _I32 _I32 _BYTES _I32 _I32);*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* ------------------------------------------------- CRYPTO --------------------------------------------------- */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								typedef unsigned int uint32;
							 | 
						||
| 
								 | 
							
								typedef unsigned char uint8;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								typedef struct {
							 | 
						||
| 
								 | 
							
								    uint32 total[2];
							 | 
						||
| 
								 | 
							
								    uint32 state[4];
							 | 
						||
| 
								 | 
							
								    uint8 buffer[64];
							 | 
						||
| 
								 | 
							
								} md5_context;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define GET_UINT32(n,b,i)                       \
							 | 
						||
| 
								 | 
							
								{                                               \
							 | 
						||
| 
								 | 
							
								    (n) = ( (uint32) (b)[(i)    ]       )       \
							 | 
						||
| 
								 | 
							
								        | ( (uint32) (b)[(i) + 1] <<  8 )       \
							 | 
						||
| 
								 | 
							
								        | ( (uint32) (b)[(i) + 2] << 16 )       \
							 | 
						||
| 
								 | 
							
								        | ( (uint32) (b)[(i) + 3] << 24 );      \
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define PUT_UINT32(n,b,i)                       \
							 | 
						||
| 
								 | 
							
								{                                               \
							 | 
						||
| 
								 | 
							
								    (b)[(i)    ] = (uint8) ( (n)       );       \
							 | 
						||
| 
								 | 
							
								    (b)[(i) + 1] = (uint8) ( (n) >>  8 );       \
							 | 
						||
| 
								 | 
							
								    (b)[(i) + 2] = (uint8) ( (n) >> 16 );       \
							 | 
						||
| 
								 | 
							
								    (b)[(i) + 3] = (uint8) ( (n) >> 24 );       \
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void md5_starts( md5_context *ctx ) {
							 | 
						||
| 
								 | 
							
								    ctx->total[0] = 0;
							 | 
						||
| 
								 | 
							
								    ctx->total[1] = 0;
							 | 
						||
| 
								 | 
							
								    ctx->state[0] = 0x67452301;
							 | 
						||
| 
								 | 
							
								    ctx->state[1] = 0xEFCDAB89;
							 | 
						||
| 
								 | 
							
								    ctx->state[2] = 0x98BADCFE;
							 | 
						||
| 
								 | 
							
								    ctx->state[3] = 0x10325476;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void md5_process( md5_context *ctx, uint8 data[64] ) {
							 | 
						||
| 
								 | 
							
								    uint32 X[16], A, B, C, D;
							 | 
						||
| 
								 | 
							
								    GET_UINT32( X[0],  data,  0 );
							 | 
						||
| 
								 | 
							
								    GET_UINT32( X[1],  data,  4 );
							 | 
						||
| 
								 | 
							
								    GET_UINT32( X[2],  data,  8 );
							 | 
						||
| 
								 | 
							
								    GET_UINT32( X[3],  data, 12 );
							 | 
						||
| 
								 | 
							
								    GET_UINT32( X[4],  data, 16 );
							 | 
						||
| 
								 | 
							
								    GET_UINT32( X[5],  data, 20 );
							 | 
						||
| 
								 | 
							
								    GET_UINT32( X[6],  data, 24 );
							 | 
						||
| 
								 | 
							
								    GET_UINT32( X[7],  data, 28 );
							 | 
						||
| 
								 | 
							
								    GET_UINT32( X[8],  data, 32 );
							 | 
						||
| 
								 | 
							
								    GET_UINT32( X[9],  data, 36 );
							 | 
						||
| 
								 | 
							
								    GET_UINT32( X[10], data, 40 );
							 | 
						||
| 
								 | 
							
								    GET_UINT32( X[11], data, 44 );
							 | 
						||
| 
								 | 
							
								    GET_UINT32( X[12], data, 48 );
							 | 
						||
| 
								 | 
							
								    GET_UINT32( X[13], data, 52 );
							 | 
						||
| 
								 | 
							
								    GET_UINT32( X[14], data, 56 );
							 | 
						||
| 
								 | 
							
								    GET_UINT32( X[15], data, 60 );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define P(a,b,c,d,k,s,t)                                \
							 | 
						||
| 
								 | 
							
								{                                                       \
							 | 
						||
| 
								 | 
							
								    a += F(b,c,d) + X[k] + t; a = S(a,s) + b;           \
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    A = ctx->state[0];
							 | 
						||
| 
								 | 
							
								    B = ctx->state[1];
							 | 
						||
| 
								 | 
							
								    C = ctx->state[2];
							 | 
						||
| 
								 | 
							
								    D = ctx->state[3];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define F(x,y,z) (z ^ (x & (y ^ z)))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    P( A, B, C, D,  0,  7, 0xD76AA478 );
							 | 
						||
| 
								 | 
							
								    P( D, A, B, C,  1, 12, 0xE8C7B756 );
							 | 
						||
| 
								 | 
							
								    P( C, D, A, B,  2, 17, 0x242070DB );
							 | 
						||
| 
								 | 
							
								    P( B, C, D, A,  3, 22, 0xC1BDCEEE );
							 | 
						||
| 
								 | 
							
								    P( A, B, C, D,  4,  7, 0xF57C0FAF );
							 | 
						||
| 
								 | 
							
								    P( D, A, B, C,  5, 12, 0x4787C62A );
							 | 
						||
| 
								 | 
							
								    P( C, D, A, B,  6, 17, 0xA8304613 );
							 | 
						||
| 
								 | 
							
								    P( B, C, D, A,  7, 22, 0xFD469501 );
							 | 
						||
| 
								 | 
							
								    P( A, B, C, D,  8,  7, 0x698098D8 );
							 | 
						||
| 
								 | 
							
								    P( D, A, B, C,  9, 12, 0x8B44F7AF );
							 | 
						||
| 
								 | 
							
								    P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
							 | 
						||
| 
								 | 
							
								    P( B, C, D, A, 11, 22, 0x895CD7BE );
							 | 
						||
| 
								 | 
							
								    P( A, B, C, D, 12,  7, 0x6B901122 );
							 | 
						||
| 
								 | 
							
								    P( D, A, B, C, 13, 12, 0xFD987193 );
							 | 
						||
| 
								 | 
							
								    P( C, D, A, B, 14, 17, 0xA679438E );
							 | 
						||
| 
								 | 
							
								    P( B, C, D, A, 15, 22, 0x49B40821 );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#undef F
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define F(x,y,z) (y ^ (z & (x ^ y)))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    P( A, B, C, D,  1,  5, 0xF61E2562 );
							 | 
						||
| 
								 | 
							
								    P( D, A, B, C,  6,  9, 0xC040B340 );
							 | 
						||
| 
								 | 
							
								    P( C, D, A, B, 11, 14, 0x265E5A51 );
							 | 
						||
| 
								 | 
							
								    P( B, C, D, A,  0, 20, 0xE9B6C7AA );
							 | 
						||
| 
								 | 
							
								    P( A, B, C, D,  5,  5, 0xD62F105D );
							 | 
						||
| 
								 | 
							
								    P( D, A, B, C, 10,  9, 0x02441453 );
							 | 
						||
| 
								 | 
							
								    P( C, D, A, B, 15, 14, 0xD8A1E681 );
							 | 
						||
| 
								 | 
							
								    P( B, C, D, A,  4, 20, 0xE7D3FBC8 );
							 | 
						||
| 
								 | 
							
								    P( A, B, C, D,  9,  5, 0x21E1CDE6 );
							 | 
						||
| 
								 | 
							
								    P( D, A, B, C, 14,  9, 0xC33707D6 );
							 | 
						||
| 
								 | 
							
								    P( C, D, A, B,  3, 14, 0xF4D50D87 );
							 | 
						||
| 
								 | 
							
								    P( B, C, D, A,  8, 20, 0x455A14ED );
							 | 
						||
| 
								 | 
							
								    P( A, B, C, D, 13,  5, 0xA9E3E905 );
							 | 
						||
| 
								 | 
							
								    P( D, A, B, C,  2,  9, 0xFCEFA3F8 );
							 | 
						||
| 
								 | 
							
								    P( C, D, A, B,  7, 14, 0x676F02D9 );
							 | 
						||
| 
								 | 
							
								    P( B, C, D, A, 12, 20, 0x8D2A4C8A );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#undef F
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								#define F(x,y,z) (x ^ y ^ z)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    P( A, B, C, D,  5,  4, 0xFFFA3942 );
							 | 
						||
| 
								 | 
							
								    P( D, A, B, C,  8, 11, 0x8771F681 );
							 | 
						||
| 
								 | 
							
								    P( C, D, A, B, 11, 16, 0x6D9D6122 );
							 | 
						||
| 
								 | 
							
								    P( B, C, D, A, 14, 23, 0xFDE5380C );
							 | 
						||
| 
								 | 
							
								    P( A, B, C, D,  1,  4, 0xA4BEEA44 );
							 | 
						||
| 
								 | 
							
								    P( D, A, B, C,  4, 11, 0x4BDECFA9 );
							 | 
						||
| 
								 | 
							
								    P( C, D, A, B,  7, 16, 0xF6BB4B60 );
							 | 
						||
| 
								 | 
							
								    P( B, C, D, A, 10, 23, 0xBEBFBC70 );
							 | 
						||
| 
								 | 
							
								    P( A, B, C, D, 13,  4, 0x289B7EC6 );
							 | 
						||
| 
								 | 
							
								    P( D, A, B, C,  0, 11, 0xEAA127FA );
							 | 
						||
| 
								 | 
							
								    P( C, D, A, B,  3, 16, 0xD4EF3085 );
							 | 
						||
| 
								 | 
							
								    P( B, C, D, A,  6, 23, 0x04881D05 );
							 | 
						||
| 
								 | 
							
								    P( A, B, C, D,  9,  4, 0xD9D4D039 );
							 | 
						||
| 
								 | 
							
								    P( D, A, B, C, 12, 11, 0xE6DB99E5 );
							 | 
						||
| 
								 | 
							
								    P( C, D, A, B, 15, 16, 0x1FA27CF8 );
							 | 
						||
| 
								 | 
							
								    P( B, C, D, A,  2, 23, 0xC4AC5665 );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#undef F
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define F(x,y,z) (y ^ (x | ~z))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    P( A, B, C, D,  0,  6, 0xF4292244 );
							 | 
						||
| 
								 | 
							
								    P( D, A, B, C,  7, 10, 0x432AFF97 );
							 | 
						||
| 
								 | 
							
								    P( C, D, A, B, 14, 15, 0xAB9423A7 );
							 | 
						||
| 
								 | 
							
								    P( B, C, D, A,  5, 21, 0xFC93A039 );
							 | 
						||
| 
								 | 
							
								    P( A, B, C, D, 12,  6, 0x655B59C3 );
							 | 
						||
| 
								 | 
							
								    P( D, A, B, C,  3, 10, 0x8F0CCC92 );
							 | 
						||
| 
								 | 
							
								    P( C, D, A, B, 10, 15, 0xFFEFF47D );
							 | 
						||
| 
								 | 
							
								    P( B, C, D, A,  1, 21, 0x85845DD1 );
							 | 
						||
| 
								 | 
							
								    P( A, B, C, D,  8,  6, 0x6FA87E4F );
							 | 
						||
| 
								 | 
							
								    P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
							 | 
						||
| 
								 | 
							
								    P( C, D, A, B,  6, 15, 0xA3014314 );
							 | 
						||
| 
								 | 
							
								    P( B, C, D, A, 13, 21, 0x4E0811A1 );
							 | 
						||
| 
								 | 
							
								    P( A, B, C, D,  4,  6, 0xF7537E82 );
							 | 
						||
| 
								 | 
							
								    P( D, A, B, C, 11, 10, 0xBD3AF235 );
							 | 
						||
| 
								 | 
							
								    P( C, D, A, B,  2, 15, 0x2AD7D2BB );
							 | 
						||
| 
								 | 
							
								    P( B, C, D, A,  9, 21, 0xEB86D391 );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#undef F
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ctx->state[0] += A;
							 | 
						||
| 
								 | 
							
								    ctx->state[1] += B;
							 | 
						||
| 
								 | 
							
								    ctx->state[2] += C;
							 | 
						||
| 
								 | 
							
								    ctx->state[3] += D;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void md5_update( md5_context *ctx, uint8 *input, uint32 length ) {
							 | 
						||
| 
								 | 
							
								    uint32 left, fill;
							 | 
						||
| 
								 | 
							
								    if( !length )
							 | 
						||
| 
								 | 
							
										return;
							 | 
						||
| 
								 | 
							
								    left = ctx->total[0] & 0x3F;
							 | 
						||
| 
								 | 
							
								    fill = 64 - left;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ctx->total[0] += length;
							 | 
						||
| 
								 | 
							
								    ctx->total[0] &= 0xFFFFFFFF;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if( ctx->total[0] < length )
							 | 
						||
| 
								 | 
							
								        ctx->total[1]++;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if( left && length >= fill ) {
							 | 
						||
| 
								 | 
							
								        memcpy( (void *) (ctx->buffer + left),
							 | 
						||
| 
								 | 
							
								                (void *) input, fill );
							 | 
						||
| 
								 | 
							
								        md5_process( ctx, ctx->buffer );
							 | 
						||
| 
								 | 
							
								        length -= fill;
							 | 
						||
| 
								 | 
							
								        input  += fill;
							 | 
						||
| 
								 | 
							
								        left = 0;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    while( length >= 64 ) {
							 | 
						||
| 
								 | 
							
								        md5_process( ctx, input );
							 | 
						||
| 
								 | 
							
								        length -= 64;
							 | 
						||
| 
								 | 
							
								        input  += 64;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if( length ) {
							 | 
						||
| 
								 | 
							
								        memcpy( (void *) (ctx->buffer + left),
							 | 
						||
| 
								 | 
							
								                (void *) input, length );
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static uint8 md5_padding[64] =
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
							 | 
						||
| 
								 | 
							
								    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
							 | 
						||
| 
								 | 
							
								    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
							 | 
						||
| 
								 | 
							
								    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void md5_finish( md5_context *ctx, uint8 digest[16] ) {
							 | 
						||
| 
								 | 
							
								    uint32 last, padn;
							 | 
						||
| 
								 | 
							
								    uint32 high, low;
							 | 
						||
| 
								 | 
							
								    uint8 msglen[8];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    high = ( ctx->total[0] >> 29 )
							 | 
						||
| 
								 | 
							
								         | ( ctx->total[1] <<  3 );
							 | 
						||
| 
								 | 
							
								    low  = ( ctx->total[0] <<  3 );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    PUT_UINT32( low,  msglen, 0 );
							 | 
						||
| 
								 | 
							
								    PUT_UINT32( high, msglen, 4 );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    last = ctx->total[0] & 0x3F;
							 | 
						||
| 
								 | 
							
								    padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    md5_update( ctx, md5_padding, padn );
							 | 
						||
| 
								 | 
							
								    md5_update( ctx, msglen, 8 );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    PUT_UINT32( ctx->state[0], digest,  0 );
							 | 
						||
| 
								 | 
							
								    PUT_UINT32( ctx->state[1], digest,  4 );
							 | 
						||
| 
								 | 
							
								    PUT_UINT32( ctx->state[2], digest,  8 );
							 | 
						||
| 
								 | 
							
								    PUT_UINT32( ctx->state[3], digest, 12 );
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "sha1.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								HL_PRIM void HL_NAME(digest)( vbyte *out, vbyte *in, int length, int format ) {
							 | 
						||
| 
								 | 
							
									if( format & 256 ) {
							 | 
						||
| 
								 | 
							
										in = (vbyte*)hl_to_utf8((uchar*)in);
							 | 
						||
| 
								 | 
							
										length = (int)strlen((char*)in);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									hl_blocking(true);
							 | 
						||
| 
								 | 
							
									switch( format & 0xFF ) {
							 | 
						||
| 
								 | 
							
									case 0:
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											md5_context ctx;
							 | 
						||
| 
								 | 
							
											md5_starts(&ctx);
							 | 
						||
| 
								 | 
							
											md5_update(&ctx,in,(uint32)length);
							 | 
						||
| 
								 | 
							
											md5_finish(&ctx,out);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										break;
							 | 
						||
| 
								 | 
							
									case 1:
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											SHA1_CTX ctx;
							 | 
						||
| 
								 | 
							
											sha1_init(&ctx);
							 | 
						||
| 
								 | 
							
											sha1_update(&ctx,in,length);
							 | 
						||
| 
								 | 
							
											sha1_final(&ctx,out);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										break;
							 | 
						||
| 
								 | 
							
									case 2:
							 | 
						||
| 
								 | 
							
										*((int*)out) = crc32(*(int*)out, in, length);
							 | 
						||
| 
								 | 
							
										break;
							 | 
						||
| 
								 | 
							
									case 3:
							 | 
						||
| 
								 | 
							
										*((int*)out) = adler32(*(int*)out, in, length);
							 | 
						||
| 
								 | 
							
										break;
							 | 
						||
| 
								 | 
							
									default:
							 | 
						||
| 
								 | 
							
										hl_blocking(false);
							 | 
						||
| 
								 | 
							
										hl_error("Unknown digest format %d",format&0xFF);
							 | 
						||
| 
								 | 
							
										break;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									hl_blocking(false);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								DEFINE_PRIM(_VOID, digest, _BYTES _BYTES _I32 _I32);
							 |