// Copyright (C) 2002-2007 Nikolaus Gebhardt // This file is part of the "Irrlicht Engine". // For conditions of distribution and use, see copyright notice in irrlicht.h // // This file was originally written by ZDimitor. //---------------------------------------------------------------------- // somefuncs.h - part of the My3D Tools // // This tool was created by Zhuck Dmitry (ZDimitor). // Everyone can use it as wants ( i'll be happy if it helps to someone :) ). //---------------------------------------------------------------------- //********************************************************************** // some usefull functions //********************************************************************** #ifndef __C_MY3D_HELPER_H_INCLUDED__ #define __C_MY3D_HELPER_H_INCLUDED__ //-------------------------------------------------------------------------------- namespace irr { namespace core { //--------------------------------------------------------------------- inline f32 fmax(f32 v1, f32 v2) { return (v1>v2)?v1:v2; } //---------------------------------------------------------------------------- template s32 strlen(T* str) { int len = 0; while(true) { if (*(str+len)==0) break; len++; } return len; } //---------------------------------------------------------------------------- template T* strcpy (T* src, T* dst) { if (src&&dst) { s32 len = strlen(src); for (s32 i=0; i T* strcpy (T* src, T* dst, s32 startPos, s32 endPos) { if (src&&dst) { s32 len = strlen(src); s32 charIndex=0; for (s32 i=startPos; i<=endPos && endPos s32 findLast(T* Str, c8 ch) { s32 lenSrc = strlen(Str); s32 n=lenSrc-1; s32 lastCharInStringPos = -1; while(true) { if (Str[n] == ch) { lastCharInStringPos = n; break; } if (n==0) break; n--; } return lastCharInStringPos; } //---------------------------------------------------------------------------- template s32 findLastDelimiter(T* Str) { s32 lenSrc = strlen(Str); s32 n=lenSrc-1; s32 lastDelimiterInStringPos = -1; while(true) { if (Str[n] == '\\' || Str[n] == '/') { lastDelimiterInStringPos = n; break; } if (n==0) break; n--; } return lastDelimiterInStringPos; } //---------------------------------------------------------------------------- template T* extractFilePath(T* sourceStr, T* buffer, s32 bufSize) { s32 lastDelimiterInStringPos = findLastDelimiter(sourceStr); if (lastDelimiterInStringPos>=0 && lastDelimiterInStringPos T* extractFileName(T* sourceStr, T* buffer, s32 bufSize) { s32 lastDelimiterInStringPos = findLastDelimiter(sourceStr); s32 lenSrc = strlen(sourceStr); if (lastDelimiterInStringPos>=-1 && (lenSrc-lastDelimiterInStringPos) 128, or EOD, or non-match. // return values: LIMIT, EOD_FOUND, NON_MATCH // Prior to ANY return, it writes out the 2 byte compressed code. // If a NON_MATCH was found, this returns with the non-matching char // residing in tmpbuf[0]. // Inputs: tmpbuf[0], input file // Outputs: tmpbuf[0] (sometimes), output file, and return code //------------------------------------------------------------------ unsigned long process_comp( unsigned char *buf, int buf_size, unsigned char *out_buf, int out_buf_size) { // we start out with 3 repeating bytes register int len = 3; unsigned char ch; // we're starting a repeating chunk - end the non-repeaters flush_outbuf(out_buf, out_buf_size); while (get_byte(&ch, buf, buf_size, out_buf, out_buf_size) != (int)EOD) { if (ch != tmpbuf[1]) { // send no. of repeated bytes to be encoded put_byte((unsigned char)((--len) | 0x80), out_buf, out_buf_size); // send the byte's value being repeated put_byte((unsigned char)tmpbuf[1], out_buf, out_buf_size); /* save the non-matching character just read */ tmpbuf[1]=(unsigned char) ch; return NON_MATCH; } /* we know the new byte is part of the repeating seq */ len++; if (len == 128) { // send no. of repeated bytes to be encoded put_byte((unsigned char)((--len) | 0x80), out_buf, out_buf_size); // send the byte's value being repeated put_byte((unsigned char)tmpbuf[1], out_buf, out_buf_size); return LIMIT; } } // end while // if flow comes here, we just read an EOD // send no. of repeated bytes to be encoded put_byte((unsigned char)((--len) | 0x80), out_buf, out_buf_size); // send the byte's value being repeated put_byte((unsigned char)tmpbuf[1], out_buf, out_buf_size); return EOD_FOUND; } //---------------------------------------------------------------- // This adds 1 non-repeating byte to outbuf. If outbuf becomes full // with 128 bytes, it flushes outbuf. // There are no return codes and no bytes are read from the input. //---------------------------------------------------------------- void process_uncomp( unsigned char char1, unsigned char *out_buf, int out_buf_size ) { outbuf[outbuf_cnt++] = char1; if (outbuf_cnt == 128) flush_outbuf(out_buf, out_buf_size); } //----------------------------------------------------------- // This flushes any non-compressed data not yet sent. // On exit, outbuf_cnt will equal zero. //----------------------------------------------------------- void flush_outbuf(unsigned char *out_buf, int out_buf_size) { register int pos=0; if(!outbuf_cnt) return; // nothing to do */ // send no. of unencoded bytes to be sent put_byte((unsigned char)(outbuf_cnt - 1), out_buf, out_buf_size); for ( ; outbuf_cnt; outbuf_cnt--) put_byte((unsigned char)outbuf[pos++], out_buf, out_buf_size); } //--------------------------------------------------- void put_byte(unsigned char ch, unsigned char *out_buf, int out_buf_size) { if (nCodedBytes<=(out_buf_size-1)) { out_buf[nCodedBytes++]=ch; out_buf[nCodedBytes]=0; } } //--------------------------------------------------- // This reads the next byte into ch. It returns EOD // at end-of-data //--------------------------------------------------- unsigned long get_byte( unsigned char *ch, unsigned char *in_buf, int in_buf_size, unsigned char *out_buf, int out_buf_size ) { if (nReadedBytes>=in_buf_size) { // there are either 0, 1, or 2 char's to write before we quit if (tmpbuf_cnt == 1) process_uncomp(tmpbuf[1], out_buf, out_buf_size); else { if (tmpbuf_cnt == 2) { process_uncomp(tmpbuf[1], out_buf, out_buf_size); process_uncomp(tmpbuf[2], out_buf, out_buf_size); } } nReadedBytes =0; return EOD; } (*ch) = (unsigned char)in_buf[nReadedBytes++]; return 0; } //----------------------------------------------------------- int rle_decode ( unsigned char *in_buf, int in_buf_size, unsigned char *out_buf, int out_buf_size ) { nDecodedBytes=0; nReadedBytes=0; int ch, i; while (1) { if (nReadedBytes>=in_buf_size) break; else ch=in_buf[nReadedBytes]; nReadedBytes++; if (ch > 127) { i = ch - 127; // i is the number of repetitions // get the byte to be repeated if (nReadedBytes>=in_buf_size) break; else ch=in_buf[nReadedBytes]; nReadedBytes++; // uncompress a chunk for ( ; i ; i--) { if (nDecodedBytes=in_buf_size) break; else ch=in_buf[nReadedBytes]; nReadedBytes++; if (nDecodedBytes