Login

Subversion Repositories NedoOS

Rev

Blame | Last modification | View Log | Download | RSS feed

// this is not a code to be separately compiled!
// instead, it is included in mhmt-depack.c several times and depends on existing at include moment #define's to generate some compiling code
//
//                   // example defines:
//#define DPK_CHECK  // check input stream for consistency
//#define DPK_DEPACK // do depacking
//#define DPK_REPERR // report errors via printf
{
        LONG i;

        ULONG check;
        ULONG byte,bits;//,bitlen;
        LONG  disp;
        ULONG length;

        ULONG stop;


        ULONG success = 1;


        // rewind input stream
        //
        check = depack_getbyte(DEPACK_GETBYTE_REWIND);
#ifdef DPK_CHECK
        if( 0xFFFFFFFF == check )
        {
 #ifdef DPK_REPERR
                printf("mhmt-depack-hrum.c:{} - Can't rewind input stream!\n");
 #endif
                return 0;
        }
#endif


        // manage zx header if needed
        if( wrk.zxheader )
        {
                // skip 5 bytes (they will go to the end of output file)
                for(i=0;i<5;i++)
                {
                        check = depack_getbyte(DEPACK_GETBYTE_NEXT);
#ifdef DPK_CHECK
                        if( 0xFFFFFFFF == check ) goto NO_BYTE_HRM;
#endif
                }

                // next 2 bytes must be 0x10
                for(i=0;i<2;i++)
                {
                        check = depack_getbyte(DEPACK_GETBYTE_NEXT);
#ifdef DPK_CHECK
                        if( 0xFFFFFFFF == check ) goto NO_BYTE_HRM;
                        if( check != 0x0010 )
                        {
 #ifdef DPK_REPERR
                                printf("mhmt-depack-hrum.c:{} - Wrong ZX-header!\n");
 #endif
                                return 0;
                        }
#endif
                }
        }



        // initialize bitstream first
        //
        check = depack_getbits(16,DEPACK_GETBITS_FORCE); // number 16 is ignored! - just for convenience here...
#ifdef DPK_CHECK
        if( 0xFFFFFFFF == check )
        {
NO_BITS_HRM:
 #ifdef DPK_REPERR
                printf("mhmt-depack-hrum.c:{} - Can't get bits from input stream!\n");
 #endif
                return 0;
        }
#endif



        // then byte of input stream goes to the output unchanged
        //
        byte = depack_getbyte(DEPACK_GETBYTE_NEXT);
#ifdef DPK_CHECK
        if( 0xFFFFFFFF == byte )
        {
NO_BYTE_HRM:
 #ifdef DPK_REPERR
                printf("mhmt-depack-hrum.c:{} - Can't get byte from input stream!\n");
 #endif
                return 0;
        }
#endif

#ifdef DPK_DEPACK
        success = success && depack_outbyte( (UBYTE)(0x00FF&byte), DEPACK_OUTBYTE_ADD );
#endif



        // now normal depacking loop
        //
        stop = 0;
        while( (!stop) && success )
        {
                bits = depack_getbits(1,DEPACK_GETBITS_NEXT);
#ifdef DPK_CHECK
                if( 0xFFFFFFFF == bits ) goto NO_BITS_HRM;
#endif

                if( 1&bits ) // %1<byte>
                {
                        byte = depack_getbyte(DEPACK_GETBYTE_NEXT);
#ifdef DPK_CHECK
                        if( 0xFFFFFFFF == byte ) goto NO_BYTE_HRM;
#endif

#ifdef DPK_DEPACK
                        success = success && depack_outbyte( (UBYTE)(0x00FF&byte), DEPACK_OUTBYTE_ADD );
#endif
                }
                else // %0xx
                {
                        bits = depack_getbits(2,DEPACK_GETBITS_NEXT);
#ifdef DPK_CHECK
                        if( 0xFFFFFFFF == bits ) goto NO_BITS_HRM;
#endif

                        switch( 0x03 & bits )
                        {
                        case 0x00: // %000xxx

                                bits = depack_getbits(3,DEPACK_GETBITS_NEXT);
#ifdef DPK_CHECK
                                if( 0xFFFFFFFF == bits ) goto NO_BITS_HRM;
#endif

                                disp = (-8) | (bits&0x07); // FFFFFFF8..FFFFFFFF (-8..-1)
#ifdef DPK_CHECK
                                if( (ULONG)(-disp) > wrk.maxwin )
                                {
WRONG_DISP_HRM:
 #ifdef DPK_REPERR
                                        printf("mhmt-depack-hrum.c:{} - Wrong lookback displacement of %d, greater than maxwin\n",(-disp) );
 #endif
                                        return 0;
                                }
#endif

#ifdef DPK_DEPACK
                                success = success && depack_repeat(disp,1);
#endif
                                break;


                        case 0x01: // %001

                                byte = depack_getbyte(DEPACK_GETBYTE_NEXT);
#ifdef DPK_CHECK
                                if( 0xFFFFFFFF == byte ) goto NO_BYTE_HRM;
#endif

                                disp = (-256) | (0x00FF&byte); // -1..-256
#ifdef DPK_CHECK
                                if( (ULONG)(-disp) > wrk.maxwin ) goto WRONG_DISP_HRM;
#endif

#ifdef DPK_DEPACK
                                success = success && depack_repeat(disp,2);
#endif
                                break;

                        default: // %010 or %011

                                if( (bits&3)==2 ) // %010 - 3 bytes
                                {
                                        length = 3;
                                }
                                else // %011 - varlen
                                {
                                        bits = depack_getbits(2,DEPACK_GETBITS_NEXT);
#ifdef DPK_CHECK
                                        if( 0xFFFFFFFF == bits ) goto NO_BITS_HRM;
#endif
                                        //  fetch len
                                        if( bits == 0x00 ) // %01100<len>, if <len>==0 - stop
                                        {
                                                length = depack_getbyte(DEPACK_GETBYTE_NEXT);
#ifdef DPK_CHECK
                                                if( 0xFFFFFFFF == length ) goto NO_BYTE_HRM;
#endif
                                                if( length == 0 )
                                                        stop = 1;
                                        }
                                        else if( bits == 0x01 ) // %01101 - len=4
                                        {
                                                length = 4;
                                        }
                                        else if( bits == 0x02 ) // %01110 - len=5
                                        {
                                                length = 5;
                                        }
                                        else // %01111
                                        {
                                                bits = depack_getbits(2,DEPACK_GETBITS_NEXT);
#ifdef DPK_CHECK
                                                if( 0xFFFFFFFF == bits ) goto NO_BITS_HRM;
#endif
                                                if( bits == 0x00 ) // %0111100
                                                {
                                                        length = 6;
                                                }
                                                else if( bits == 0x01 ) // %0111101
                                                {
                                                        length = 7;
                                                }
                                                else if( bits == 0x02 ) // %0111110
                                                {
                                                        length = 8;
                                                }
                                                else // %0111111
                                                {
                                                        bits = depack_getbits(2,DEPACK_GETBITS_NEXT);
#ifdef DPK_CHECK
                                                        if( 0xFFFFFFFF == bits ) goto NO_BITS_HRM;
#endif
                                                        if( bits == 0x00 ) // %011111100
                                                        {
                                                                length = 9;
                                                        }
                                                        else if( bits == 0x01 ) // %011111101
                                                        {
                                                                length = 10;
                                                        }
                                                        else if( bits == 0x02 ) // %011111110
                                                        {
                                                                length = 11;
                                                        }
                                                        else // %011111111
                                                        {
                                                                bits = depack_getbits(2,DEPACK_GETBITS_NEXT);
#ifdef DPK_CHECK
                                                                if( 0xFFFFFFFF == bits ) goto NO_BITS_HRM;
#endif
                                                                if( bits == 0x00 ) // %01111111100
                                                                {
                                                                        length = 12;
                                                                }
                                                                else if( bits == 0x01 ) // %01111111101
                                                                {
                                                                        length = 13;
                                                                }
                                                                else if( bits == 0x02 ) // %01111111110
                                                                {
                                                                        length = 14;
                                                                }
                                                                else // %01111111111
                                                                {
                                                                        length = 15;
                                                                }
                                                        }
                                                }
                                        }
                                }


                                // fetch disp and depack
                                if( !stop )
                                {
                                        bits = depack_getbits(1,DEPACK_GETBITS_NEXT);
#ifdef DPK_CHECK
                                        if( 0xFFFFFFFF == bits ) goto NO_BITS_HRM;
#endif
                                        if( bits == 0x00 ) // %0<disp>
                                        {
                                                byte = depack_getbyte(DEPACK_GETBYTE_NEXT);
#ifdef DPK_CHECK
                                                if( 0xFFFFFFFF == byte ) goto NO_BYTE_HRM;
#endif
                                                disp = (-256) | (0x00FF&byte); // -1..-256
#ifdef DPK_CHECK
                                                if( (ULONG)(-disp) > wrk.maxwin ) goto WRONG_DISP_HRM;
#endif
#ifdef DPK_DEPACK
                                                success = success && depack_repeat(disp,length);
#endif
                                        }
                                        else // %1abcd<disp>
                                        {
                                                bits = depack_getbits(4,DEPACK_GETBITS_NEXT);
#ifdef DPK_CHECK
                                                if( 0xFFFFFFFF == bits ) goto NO_BITS_HRM;
#endif
                                                byte = depack_getbyte(DEPACK_GETBYTE_NEXT);
#ifdef DPK_CHECK
                                                if( 0xFFFFFFFF == byte ) goto NO_BYTE_HRM;
#endif
                                                disp = (-4096) | (0x0F00&(bits<<8)) | (0x00FF&byte); // -1..-4096
#ifdef DPK_CHECK
                                                if( (ULONG)(-disp) > wrk.maxwin ) goto WRONG_DISP_HRM;
#endif
#ifdef DPK_DEPACK
                                                success = success && depack_repeat(disp,length);
#endif
                                        }
                                }

                                break;
                        }
                }
        }

        //manage zxheader again (copy to the end of output)
#ifdef DPK_DEPACK
        if( wrk.zxheader )
        {
                check = depack_getbyte(DEPACK_GETBYTE_REWIND);
 #ifdef DPK_CHECK
                if( 0xFFFFFFFF == check )
                {
  #ifdef DPK_REPERR
                        printf("mhmt-depack-hrum.c:{} - Can't rewind input stream!\n");
  #endif
                        return 0;
                }
 #endif

                // place 5 bytes of header to the end
                for(i=0;i<5;i++)
                {
                        byte = depack_getbyte(DEPACK_GETBYTE_NEXT);
 #ifdef DPK_CHECK
                        if( 0xFFFFFFFF == check ) goto NO_BYTE_HRM:
 #endif
                        success = success && depack_outbyte( (UBYTE)(0x00FF&byte), DEPACK_OUTBYTE_ADD );
                }
        }
#endif

        return success;
}