cr88192

A basic RP2 encoder/decoder (byte-based fast LZ).

Jul 16th, 2026
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 16.81 KB | Source Code | 0 0
  1. /*
  2. Basic RP2/RP2B encoder/decoder.
  3.  
  4. RP2 (Transposed, LE):
  5. *                        dddddddd-dlllrrr0  (l=3..10, d=0..511, r=0..7)
  6. *               dddddddd-dddddlll-lllrrr01  (l=4..67, d=0..8191)
  7. *      dddddddd-dddddddd-dlllllll-llrrr011  (l=4..515, d=0..131071)
  8. *                                 rrrr0111  (Raw Bytes, r=(r+1)*8, 8..128)
  9. *                               * rrr01111  (Long Match)
  10. *                                 rr011111  (r=1..3 bytes, 0=EOB)
  11. *                        rrrrrrrr-r0111111  (Long Raw, r=(r+1)*8, 8..4096)
  12. *                        lllllll0-01111111  (RP2B, l=4..131, d=1, r=0)
  13. * 2x D-ddddddll-llllllll-llllrrr1-01111111  (RP2B, l=4..16K, d=0..4M, r=0..7)
  14. *
  15. ** d: Distance
  16. ** l: Match Length
  17. ** r: Literal Length
  18.  
  19. The original long match is excluded.
  20.  
  21.  
  22. Portability:
  23. Assumes a target that allows fast unaligned memory dereference and little-endian word ordering. While not strictly portable, casting to a volatile pointer is usually enough to stop compilers from getting stupid, without the speed penalty of more "approved" methods ("like memcpy()") on some other compilers, otherwise one is either fighting with performance or needing to have a bunch of alternate-case boilerplate to deal with different compilers (some which deal well with "memcpy()", others where "memcpy()" performs like hot garbage).
  24.  
  25. Granted, there are some chips around which support misaligned access, sorta, but where doing so carries a significant speed penalty (due to internal traps and emulation). Will ignore these for now.
  26.  
  27. */
  28.  
  29.  
  30. #if 1
  31. #include <stdint.h>
  32.  
  33. #ifndef GFXEDIT_BASETYPES
  34. #define GFXEDIT_BASETYPES
  35. typedef uint8_t byte;
  36. typedef int8_t      sbyte;
  37. typedef uint16_t    u16;
  38. typedef int16_t s16;
  39. typedef uint32_t    u32;
  40. typedef int32_t s32;
  41. typedef uint64_t    u64;
  42. typedef int64_t s64;
  43. typedef volatile uint16_t   vol_u16;
  44. typedef volatile uint32_t   vol_u32;
  45. typedef volatile uint64_t   vol_u64;
  46. typedef volatile uint16_t   *vol_u16p;
  47. typedef volatile uint32_t   *vol_u32p;
  48. typedef volatile uint64_t   *vol_u64p;
  49. #endif
  50.  
  51. #ifndef GFXEDIT_MISAL
  52. #define GFXEDIT_MISAL
  53. /* portability boilerplate goes here... */
  54. #define gfxedit_getu16(ptr)         (*(vol_u16p)(ptr))
  55. #define gfxedit_getu32(ptr)         (*(vol_u32p)(ptr))
  56. #define gfxedit_getu64(ptr)         (*(vol_u64p)(ptr))
  57. #define gfxedit_setu16(ptr,val)     (*(vol_u16p)(ptr)=(val))
  58. #define gfxedit_setu32(ptr,val)     (*(vol_u32p)(ptr)=(val))
  59. #define gfxedit_setu64(ptr,val)     (*(vol_u64p)(ptr)=(val))
  60. #endif
  61.  
  62. #endif
  63.  
  64. byte *gfxedit_memlzcpyf(byte *dst, byte *src, int len)
  65. {
  66.     byte *cs, *ct, *cte;
  67.     u64 v0, v1;
  68.     int d;
  69.     int i;
  70.    
  71.     d=dst-src;
  72.  
  73. #if 0
  74.     //simple/safe, but slow
  75.     if(d>len)
  76.         { memcpy(dst, src, len); return(dst+len); }
  77.     if(d<0)
  78.     {
  79.         memmove(dst, src, len);
  80.         return(dst+len);
  81.     }
  82.     if(d==1)
  83.         { memset(dst, *src, len); return(dst+len); }
  84.  
  85.     for(i=0; i<len; i++)
  86.         dst[i]=src[i];
  87.     return(dst+len);
  88. #endif
  89.  
  90. //  if((d>len) || (d<(-len)))
  91.     if(d>len)
  92.     {
  93.         cs=src;
  94.         ct=dst;
  95.         cte=dst+len;
  96.  
  97.         v0=gfxedit_getu64(cs);
  98.         v1=gfxedit_getu64(cs+8);
  99.         gfxedit_setu64(ct, v0);
  100.         gfxedit_setu64(ct+8, v1);
  101.         cs+=16; ct+=16;
  102.  
  103.         if(ct<cte)
  104.         {
  105.             v0=gfxedit_getu64(cs);
  106.             v1=gfxedit_getu64(cs+8);
  107.             gfxedit_setu64(ct, v0);
  108.             gfxedit_setu64(ct+8, v1);
  109.             cs+=16; ct+=16;
  110.  
  111.             if(ct<cte)
  112.             {
  113.                 v0=gfxedit_getu64(cs);
  114.                 v1=gfxedit_getu64(cs+8);
  115.                 gfxedit_setu64(ct, v0);
  116.                 gfxedit_setu64(ct+8, v1);
  117.                 cs+=16; ct+=16;
  118.  
  119.                 while(ct<cte)
  120.                 {
  121.                     v0=gfxedit_getu64(cs);
  122.                     v1=gfxedit_getu64(cs+8);
  123.                     gfxedit_setu64(ct, v0);
  124.                     gfxedit_setu64(ct+8, v1);
  125.                     cs+=16; ct+=16;
  126.                 }
  127.             }
  128.         }
  129.         return(cte);
  130.     }
  131.  
  132.     if(d<=8)
  133.     {
  134.         if(d==1)
  135.         {
  136.             v0=*(byte *)src;
  137.             v0|=(v0<<8); v0|=(v0<<16); v0|=(v0<<32);
  138.             ct=dst; cte=dst+len;
  139.             while(ct<cte)
  140.                 { gfxedit_setu64(ct, v0); gfxedit_setu64(ct+8, v0); ct+=16; }
  141.             return(cte);
  142.         }
  143.  
  144.         if(d==2)
  145.         {
  146.             v0=gfxedit_getu16(src);
  147.             v0|=(v0<<16); v0|=(v0<<32);
  148.             ct=dst; cte=dst+len;
  149.             while(ct<cte)
  150.                 { gfxedit_setu64(ct, v0); gfxedit_setu64(ct+8, v0); ct+=16; }
  151.             return(cte);
  152.         }
  153.  
  154.         if(d==4)
  155.         {
  156.             v0=gfxedit_getu32(src);
  157.             v0|=(v0<<32);
  158.             ct=dst; cte=dst+len;
  159.             while(ct<cte)
  160.                 { gfxedit_setu64(ct, v0); gfxedit_setu64(ct+8, v0); ct+=16; }
  161.             return(cte);
  162.         }
  163.  
  164.         if(d==8)
  165.         {
  166.             v0=gfxedit_getu64(src);
  167.             ct=dst; cte=dst+len;
  168.             while(ct<cte)
  169.                 { gfxedit_setu64(ct, v0); gfxedit_setu64(ct+8, v0); ct+=16; }
  170.             return(cte);
  171.         }
  172.  
  173.         if(d<0)
  174.         {
  175.             if(d<(-len))
  176.             {
  177.                 cs=src;
  178.                 ct=dst;
  179.                 cte=dst+len;
  180.                 while(ct<cte)
  181.                 {
  182.                     v0=gfxedit_getu64(cs);
  183.                     v1=gfxedit_getu64(cs+8);
  184.                     gfxedit_setu64(ct, v0);
  185.                     gfxedit_setu64(ct+8, v1);
  186.                     cs+=16; ct+=16;
  187.                 }
  188.                 return(cte);
  189.             }
  190.        
  191.             memmove(dst, src, len);
  192.             return(dst+len);
  193.         }
  194.  
  195. #if 0
  196.         if(d==3)
  197.         {
  198.             v0=gfxedit_getu32(src);
  199.             v0&=0x00FFFFFF;
  200.             v0|=(v0<<24);
  201.             v1=(v0>>16)|(v0<<32);
  202.             v0|=v0<<48;
  203.  
  204.             ct=dst; cte=dst+len;
  205.             while(ct<cte)
  206.                 { gfxedit_setu64(ct, v0); gfxedit_setu64(ct+8, v1); ct+=15; }
  207.             return(cte);
  208.         }
  209. #endif
  210.  
  211. #if 1
  212.         if(d==3)
  213.         {
  214.             v0=gfxedit_getu32(src);
  215.             v0=v0<<40;
  216.             v0=(v0>>16)|(v0>>40);
  217.             ct=dst; cte=dst+len;
  218.             while(ct<cte)
  219.             {
  220.                 gfxedit_setu64(ct+ 0, v0);
  221.                 gfxedit_setu64(ct+ 6, v0);
  222.                 gfxedit_setu64(ct+12, v0);
  223.                 ct+=18;
  224.             }
  225.             return(cte);
  226.         }
  227. #endif
  228.  
  229. #if 1
  230.         if(d==5)
  231.         {
  232.             v0=gfxedit_getu64(src);
  233.             ct=dst; cte=dst+len;
  234.             while(ct<cte)
  235.                 { gfxedit_setu64(ct, v0); ct+=5; }
  236.             return(cte);
  237.         }
  238.  
  239.         if(d==7)
  240.         {
  241.             v0=gfxedit_getu64(src);
  242.             ct=dst; cte=dst+len;
  243.             while(ct<cte)
  244.                 { gfxedit_setu64(ct, v0); ct+=7; }
  245.             return(cte);
  246.         }
  247. #endif
  248.  
  249.         for(i=0; i<len; i++)
  250.             dst[i]=src[i];
  251.         return(dst+len);
  252.     }
  253.  
  254.     if(d>=16)
  255.     {
  256.         cs=src;
  257.         ct=dst;
  258.         cte=dst+len;
  259.         while(ct<cte)
  260.         {
  261.             v0=gfxedit_getu64(cs);
  262.             v1=gfxedit_getu64(cs+8);
  263.             gfxedit_setu64(ct, v0);
  264.             gfxedit_setu64(ct+8, v1);
  265.             cs+=16; ct+=16;
  266.         }
  267.         return(cte);
  268.     }
  269.     else
  270.     {
  271.         cs=src;
  272.         ct=dst;
  273.         cte=dst+len;
  274.         while(ct<cte)
  275.         {
  276.             v0=gfxedit_getu64(cs);
  277.             gfxedit_setu64(ct, v0);
  278.             cs+=8; ct+=8;
  279.         }
  280.         return(cte);
  281.     }
  282. }
  283.  
  284. int GfxEdit_DecodeRP2(byte *dst, byte *src, int dsz, int ssz)
  285. {
  286.     byte *cs, *ct, *cse, *cte;
  287.     u32 tag;
  288.     int ml, md, mr, no;
  289.    
  290.     cs=src; ct=dst; cse=src+ssz; cte=dst+dsz;
  291.     no=0;
  292.     while((cs<cse) && (ct<cte))
  293.     {
  294.         tag=gfxedit_getu32(cs);
  295.         if(!(tag&0x01))
  296.         {
  297.             mr=(tag>>1)&7;
  298.             ml=((tag>>4)&7)+3;
  299.             md=(tag>>7)&511;
  300.             cs+=2;
  301.         }
  302.         else if(!(tag&0x02))
  303.         {
  304.             mr=(tag>>2)&7;
  305.             ml=((tag>>5)&63)+4;
  306.             md=(tag>>11)&8191;
  307.             cs+=3;
  308.         }
  309.         else if(!(tag&0x04))
  310.         {
  311.             mr=(tag>>3)&7;
  312.             ml=((tag>>6)&511)+4;
  313.             md=(tag>>15)&131071;
  314.             cs+=4;
  315.         }else if(!(tag&0x08))
  316.         {
  317.             mr=(((tag>>4)&15)+1)*8;
  318.             ml=0;
  319.             md=0;
  320.             cs+=1;
  321.         }else if(!(tag&0x10))
  322.         {
  323.             __debugbreak();
  324.             break;
  325.         }else if(!(tag&0x20))
  326.         {
  327.             mr=(tag>>6)&3;
  328.             ml=0;
  329.             md=0;
  330.             cs+=1;
  331.             if(!mr)
  332.                 break;
  333.         }else if(!(tag&0x40))
  334.         {
  335.             mr=(((tag>>7)&511)+1)*8;
  336.             ml=0;
  337.             md=0;
  338.             cs+=2;
  339.         }else if(!(tag&0x80))
  340.         {
  341.             if(!(tag&0x100))
  342.             {
  343.                 mr=0;
  344.                 ml=((tag>>9)&127)+4;
  345.                 md=1;
  346.                 cs+=2;
  347.             }else
  348.             {
  349.                 mr=(tag>>9)&7;
  350.                 ml=((tag>>12)&16383)+4;
  351.                 md=(gfxedit_getu32(cs+3)>>2)&0x3FFFFF;
  352.                 cs+=6;
  353.             }
  354.         }else
  355.         {
  356.             __debugbreak();
  357.             break;
  358.         }
  359.  
  360.         if(mr)
  361.         {
  362.             if(mr>8)
  363.             {
  364.                 if(mr>16)
  365.                 {
  366.                     gfxedit_memlzcpyf(ct, cs, mr);
  367.                 }else
  368.                 {
  369.                     gfxedit_setu64(ct, gfxedit_getu64(cs));
  370.                     gfxedit_setu64(ct+8, gfxedit_getu64(cs+8));
  371.                 }
  372.             }else
  373.                 { gfxedit_setu64(ct, gfxedit_getu64(cs)); }
  374.             ct+=mr;
  375.             cs+=mr;
  376.         }
  377.         if(ml)
  378.             { ct=gfxedit_memlzcpyf(ct, ct-md, ml); }
  379.     }
  380.     return(ct-dst);
  381. }
  382.  
  383.  
  384. #define GFXEDIT_MINRP2_HASHSZ       1024
  385. #define GFXEDIT_MINRP2_HASHDEPTH    16
  386.  
  387. // #define GFXEDIT_MINRP2_MAX_ML        515
  388. // #define GFXEDIT_MINRP2_MAX_MD        131071
  389.  
  390. #define GFXEDIT_MINRP2_MAX_ML       16387
  391. #define GFXEDIT_MINRP2_MAX_MD       0x3FFFFF
  392.  
  393.  
  394. #define GFXEDIT_MINRP2_HASH2SZ      4096
  395. #define GFXEDIT_MINRP2_HASH2DEPTH   4
  396.  
  397. // #define GFXEDIT_MINRP2_HASH2SZ       128
  398. // #define GFXEDIT_MINRP2_HASH2DEPTH    128
  399.  
  400. //#define GFXEDIT_MINRP2_HASH2SZ        256
  401. //#define GFXEDIT_MINRP2_HASH2DEPTH 64
  402.  
  403. // #define GFXEDIT_MINRP2_HASH2SZ       64
  404. // #define GFXEDIT_MINRP2_HASH2DEPTH    256
  405.  
  406. int GfxEdit_EncodeRP2_HashMatch(byte *cs)
  407. {
  408.     u32 h;
  409.     h=gfxedit_getu32(cs);
  410.     h^=(h<<7)^(h>>13);
  411.     h^=(h>>17);
  412.     return(h&(GFXEDIT_MINRP2_HASHSZ-1));
  413. }
  414.  
  415. #ifdef GFXEDIT_MINRP2_HASH2SZ
  416.  
  417. #if (GFXEDIT_MINRP2_HASH2SZ>1024)
  418. int GfxEdit_EncodeRP2_Hash2Match(byte *cs)
  419. {
  420.     u64 h;
  421.     /* for wide/shallow */
  422.     h=gfxedit_getu64(cs);
  423.     h^=(h>>29);
  424.     h^=(h<<7)^(h>>13);
  425.     h^=(h>>17);
  426.     return(h&(GFXEDIT_MINRP2_HASH2SZ-1));
  427. }
  428. #else
  429. int GfxEdit_EncodeRP2_Hash2Match(byte *cs)
  430. {
  431.     u32 h;
  432.     /* for narrow/deep */
  433.     h=gfxedit_getu64(cs);
  434. //  h&=0xFFFFFF;
  435.     h<<=8;
  436.     h^=(h<<7)^(h>>13);
  437.     h^=(h>>17);
  438.     return(h&(GFXEDIT_MINRP2_HASH2SZ-1));
  439. }
  440. #endif
  441.  
  442. #endif
  443.  
  444. void GfxEdit_EncodeRP2_HashUpdateByte(
  445.     byte *cs, byte *src, int *hash, byte *hrov)
  446. {
  447.     int *hashz, *hash2;
  448.     byte *hrov2;
  449.     int c0, c1, c2, c3;
  450.     int h, hr, i;
  451.  
  452.     h=GfxEdit_EncodeRP2_HashMatch(cs);
  453.     hr=hrov[h];
  454.     hash[(h*GFXEDIT_MINRP2_HASHDEPTH)+hr]=cs-src;
  455.     hrov[h]=(hr+1)&(GFXEDIT_MINRP2_HASHDEPTH-1);
  456.  
  457. #ifdef GFXEDIT_MINRP2_HASH2SZ
  458.     hash2=hash+(GFXEDIT_MINRP2_HASHSZ*GFXEDIT_MINRP2_HASHDEPTH);
  459.     hrov2=hrov+GFXEDIT_MINRP2_HASHSZ;
  460.  
  461.     h=GfxEdit_EncodeRP2_Hash2Match(cs);
  462.     hr=hrov2[h];
  463.     hash2[(h*GFXEDIT_MINRP2_HASH2DEPTH)+hr]=cs-src;
  464.     hrov2[h]=(hr+1)&(GFXEDIT_MINRP2_HASH2DEPTH-1);
  465. #endif
  466. }
  467.  
  468. int GfxEdit_EncodeRP2_CheckMatchLength(byte *s0, byte *s1, byte *cse)
  469. {
  470.     char *cs0, *cs1;
  471.     u64 v0, v1;
  472.     int ml, i;
  473.  
  474. #if 0
  475.     for(i=0; i<GFXEDIT_MINRP2_MAX_ML; i++)
  476.         if(s0[i]!=s1[i])
  477.             break;
  478.     return(i);
  479. #endif
  480.  
  481.     v0=gfxedit_getu64(s0);
  482.     v1=gfxedit_getu64(s1);
  483.     if(v0!=v1)
  484.     {
  485.         if(((u32)v0)!=((u32)v1))
  486.         {
  487.             if((v0&0xFFFFFF)==(v1&0xFFFFFF))
  488.                 return(3);
  489.             return(0);
  490.         }
  491.         v0>>=32; v1>>=32;
  492.         if(((u16)v0)!=((u16)v1))
  493.         {
  494.             if(((byte)v0)!=((byte)v1))
  495.                 return(4);
  496.             return(5);
  497.         }
  498.         v0>>=16; v1>>=16;
  499.         if(((byte)v0)!=((byte)v1))
  500.             return(6);
  501.         return(7);
  502.     }
  503.  
  504.     cs0=s0+8;
  505.     cs1=s1+8;
  506.     ml=8;
  507.  
  508.     v0=gfxedit_getu64(cs0);
  509.     v1=gfxedit_getu64(cs1);
  510.     while((v0==v1) && (cs0<cse))
  511.     {
  512.         cs0+=8; cs1+=8; ml+=8;
  513.         v0=gfxedit_getu64(cs0); v1=gfxedit_getu64(cs1);
  514.     }
  515.  
  516.     if(v0!=v1)
  517.     {
  518.         for(i=0; i<64; i+=8)
  519.             if(((v0>>i)&255)!=((v1>>i)&255))
  520.                 break;
  521.         ml+=i>>3;
  522.     }
  523.     return(ml);
  524. }
  525.  
  526. int GfxEdit_EncodeRP2_LookupMatch(byte *cs,
  527.     byte *src, int *hash, byte *hrov, byte *cse,
  528.     int *rml, int *rmd)
  529. {
  530.     int *hash2;
  531.     byte *cs1, *hrov2, *cse1;
  532.     int bl, bd, bi, d, hr;
  533.     int h, i, j, k;
  534.  
  535.     cse1=cs+GFXEDIT_MINRP2_MAX_ML;
  536.     if(cse<cse1)
  537.         cse1=cse;
  538.  
  539.     h=GfxEdit_EncodeRP2_HashMatch(cs);
  540.     hr=hrov[h]-1;
  541.     bl=0; bd=0; bi=0;
  542.     for(i=0; i<GFXEDIT_MINRP2_HASHDEPTH; i++)
  543.     {
  544.         cs1=src+hash[h*GFXEDIT_MINRP2_HASHDEPTH+
  545.             ((hr-i)&(GFXEDIT_MINRP2_HASHDEPTH-1))];
  546.         j=GfxEdit_EncodeRP2_CheckMatchLength(cs, cs1, cse1);
  547.         d=cs-cs1;
  548.         if((j>bl) && (d>0) && (d<GFXEDIT_MINRP2_MAX_MD))
  549.             { bl=j; bd=d; bi=i; }
  550.     }
  551.  
  552. #ifdef GFXEDIT_MINRP2_HASH2SZ
  553.     if(bl<8)
  554.     {
  555.         hash2=hash+(GFXEDIT_MINRP2_HASHSZ*GFXEDIT_MINRP2_HASHDEPTH);
  556.         hrov2=hrov+GFXEDIT_MINRP2_HASHSZ;
  557.  
  558.         h=GfxEdit_EncodeRP2_Hash2Match(cs);
  559.         hr=hrov2[h]-1;
  560.         for(i=0; i<GFXEDIT_MINRP2_HASH2DEPTH; i++)
  561.         {
  562.             cs1=src+hash2[h*GFXEDIT_MINRP2_HASH2DEPTH+
  563.                 ((hr-i)&(GFXEDIT_MINRP2_HASH2DEPTH-1))];
  564.             j=GfxEdit_EncodeRP2_CheckMatchLength(cs, cs1, cse1);
  565.             d=cs-cs1;
  566.             if((j>bl) && (d>0) && (d<GFXEDIT_MINRP2_MAX_MD))
  567.             {
  568.                 bl=j; bd=d; bi=i;
  569.                 if(bl>=8)
  570.                     break;
  571.             }
  572.         }
  573.     }
  574. #endif
  575.  
  576.     if((cs+bl)>cse)
  577.         bl=cse-cs;
  578.     if(bl>GFXEDIT_MINRP2_MAX_ML)
  579.         bl=GFXEDIT_MINRP2_MAX_ML;
  580.  
  581.     if(bl<3)                    bl=0;
  582.     if((bl<4) && (bd>   511))   bl=0;
  583.     if((bl<6) && (bd>  8191))   bl=0;
  584.     if((bl<8) && (bd>131071))   bl=0;
  585.    
  586.     if((bl>0) && (bd>=8192))
  587.     {
  588.         k=-1;
  589.     }
  590.    
  591.     *rml=bl;    *rmd=bd;
  592.     return(bl!=0);
  593. }
  594.  
  595. int GfxEdit_EncodeRP2_GetRawM7Cost(int mr)
  596. {
  597.     int c, k;
  598.    
  599.     c=mr; k=mr;
  600.     while(k>=4096)
  601.         { c+=2; k-=4096; }
  602.     if(k>128)
  603.     {
  604.         c+=2;
  605.         k&=7;
  606.     }else
  607.     {
  608.         c+=1;
  609.         k&=7;
  610.     }
  611.     return(c);
  612. }
  613.  
  614. int GfxEdit_EncodeRP2_GetRawM0Cost(int mr)
  615. {
  616.     int c, k;
  617.    
  618.     c=mr; k=mr;
  619.     while(k>=4096)
  620.         { c+=2; k-=4096; }
  621.     if(k>128)
  622.     {
  623.         c+=2;
  624.         k&=7;
  625.     }else
  626.     {
  627.         c+=1;
  628.         k&=7;
  629.     }
  630.     while(k>=3)
  631.         { c=+1; k-=3; }
  632.     if(k)
  633.         { c+=1; }
  634.     return(c);
  635. }
  636.  
  637. int GfxEdit_EncodeRP2_GetMatchCost(int mr, int ml, int md)
  638. {
  639.     if((ml>=3) && (ml<=10) && (md<=511))
  640.         return(2+GfxEdit_EncodeRP2_GetRawM7Cost(mr));
  641.     if((ml>=4) && (ml<=131) && (md==1) && (mr==0))
  642.         return(2+GfxEdit_EncodeRP2_GetRawM0Cost(mr));
  643.     if((ml>=4) && (ml<=67) && (md<=8191))
  644.         return(3+GfxEdit_EncodeRP2_GetRawM7Cost(mr));
  645.     if((ml>=4) && (ml<=515) && (md<=131071))
  646.         return(4+GfxEdit_EncodeRP2_GetRawM7Cost(mr));
  647.     return(6+GfxEdit_EncodeRP2_GetRawM7Cost(mr));
  648. }
  649.  
  650. int GfxEdit_EncodeRP2(byte *dst, byte *src, int dsz, int ssz)
  651. {
  652.     static int *hash;
  653.     static byte *hrov;
  654.  
  655.     byte *cs, *cs0, *ct, *cse, *cte;
  656.     u32 tag;
  657.     int ml, md, mr, h, mrt, ml1, md1, mrt1, mc1, mc2;
  658.     int i, j, k, no;
  659.  
  660.     if(!hash)
  661.     {
  662.         hash=malloc((
  663.             GFXEDIT_MINRP2_HASHSZ *GFXEDIT_MINRP2_HASHDEPTH +
  664. #ifdef GFXEDIT_MINRP2_HASH2SZ
  665.             GFXEDIT_MINRP2_HASH2SZ*GFXEDIT_MINRP2_HASH2DEPTH+
  666. #endif
  667.             0)*sizeof(int));
  668.         hrov=malloc(
  669.             GFXEDIT_MINRP2_HASHSZ+
  670. #ifdef GFXEDIT_MINRP2_HASH2SZ
  671.             GFXEDIT_MINRP2_HASH2SZ+
  672. #endif
  673.             0);
  674.     }
  675.  
  676.     memset(hash, 0,
  677.         (GFXEDIT_MINRP2_HASHSZ*GFXEDIT_MINRP2_HASHDEPTH+
  678. #ifdef GFXEDIT_MINRP2_HASH2SZ
  679.         GFXEDIT_MINRP2_HASH2SZ*GFXEDIT_MINRP2_HASH2DEPTH+
  680. #endif
  681.         0)*sizeof(int));
  682.     memset(hrov, 0,
  683.         (GFXEDIT_MINRP2_HASHSZ+
  684. #ifdef GFXEDIT_MINRP2_HASH2SZ
  685.         GFXEDIT_MINRP2_HASH2SZ+
  686. #endif
  687.         0)*sizeof(byte));
  688.    
  689.     cs=src; ct=dst; cse=src+ssz; cte=dst+dsz;
  690.     cs0=cs; no=0;
  691.     while(cs<cse)
  692.     {
  693.         mrt1=0;
  694.         mrt=GfxEdit_EncodeRP2_LookupMatch(cs, src,
  695.             hash, hrov, cse, &ml, &md);
  696.         if(mrt)
  697.         {
  698.             mrt1=GfxEdit_EncodeRP2_LookupMatch(cs+1, src,
  699.                 hash, hrov, cse, &ml1, &md1);
  700.             if(mrt1)
  701.             {
  702.                 mr=cs-cs0;
  703.                 mc1=GfxEdit_EncodeRP2_GetMatchCost(mr, ml, md);
  704.                 mc2=GfxEdit_EncodeRP2_GetMatchCost(mr+1, ml1, md1);
  705.                 if(mrt1 && (ml1>(ml+1+(mc2-mc1))))
  706.                     mrt=0;
  707.             }
  708.         }
  709.  
  710.         if(mrt)
  711.         {
  712.             mr=cs-cs0;
  713.             while(mr>128)
  714.             {
  715.                 k=(mr/8)-1;
  716.                 if(k>511)
  717.                     k=511;
  718.                 tag=0x3F|(k<<7);
  719.                 *ct++=(tag>>0)&255;
  720.                 *ct++=(tag>>8)&255;
  721.                 j=(k+1)*8;
  722.                 memcpy(ct, cs0, j);
  723.                 ct+=j; cs0+=j;
  724.                 mr=cs-cs0;
  725.             }
  726.  
  727.             while(mr>=8)
  728.             {
  729.                 k=(mr/8)-1;
  730.                 if(k>15)
  731.                     k=15;
  732.                 tag=0x07|(k<<4);
  733.                 *ct++=tag;
  734.                 j=(k+1)*8;
  735.                 memcpy(ct, cs0, j);
  736.                 ct+=j; cs0+=j;
  737.                 mr=cs-cs0;
  738.             }
  739.            
  740.             if((ml<=10) && (md<=511))
  741.             {
  742.                 tag=0|(mr<<1)|((ml-3)<<4)|(md<<7);
  743.                 *ct++=(tag>>0)&255;
  744.                 *ct++=(tag>>8)&255;
  745.                 if(mr)
  746.                 {
  747.                     memcpy(ct, cs0, mr);
  748.                     ct+=mr; cs0+=mr;
  749.                 }
  750.             }else
  751.                 if((mr==0) && (ml>=4) && (ml<=131) && (md==1))
  752.             {
  753.                 tag=0x7F|((ml-4)<<9);
  754.                 *ct++=(tag>>0)&255;
  755.                 *ct++=(tag>>8)&255;
  756.             }else
  757.                 if((ml>=4) && (ml<=67) && (md<=8191))
  758.             {
  759.                 tag=1|(mr<<2)|((ml-4)<<5)|(md<<11);
  760.                 *ct++=(tag>> 0)&255;
  761.                 *ct++=(tag>> 8)&255;
  762.                 *ct++=(tag>>16)&255;
  763.                 if(mr)
  764.                 {
  765.                     memcpy(ct, cs0, mr);
  766.                     ct+=mr; cs0+=mr;
  767.                 }
  768.             }else
  769.                 if((ml>=4) && (ml<=515) && (md<=131071))
  770.             {
  771.                 tag=3|(mr<<3)|((ml-4)<<6)|(md<<15);
  772.                 *ct++=(tag>> 0)&255;
  773.                 *ct++=(tag>> 8)&255;
  774.                 *ct++=(tag>>16)&255;
  775.                 *ct++=(tag>>24)&255;
  776.                 if(mr)
  777.                 {
  778.                     memcpy(ct, cs0, mr);
  779.                     ct+=mr; cs0+=mr;
  780.                 }
  781.             }else
  782.                 if((ml<=16387) && (md<=0x3FFFFF))
  783.             {
  784.                 tag=0x017F|(mr<<9)|((ml-4)<<12)|(md<<26);
  785.                 *ct++=(tag>> 0)&255;
  786.                 *ct++=(tag>> 8)&255;
  787.                 *ct++=(tag>>16)&255;
  788.                 *ct++=(tag>>24)&255;
  789.                 *ct++=(md >> 6)&255;
  790.                 *ct++=(md >>14)&255;
  791.                 if(mr)
  792.                 {
  793.                     memcpy(ct, cs0, mr);
  794.                     ct+=mr; cs0+=mr;
  795.                 }
  796.             }else
  797.             {
  798.                 __debugbreak();
  799.             }
  800.            
  801.             for(i=0; i<ml; i++)
  802.             {
  803.                 GfxEdit_EncodeRP2_HashUpdateByte(cs, src, hash, hrov);
  804.                 cs++;
  805.             }
  806.             cs0=cs;
  807.         }else
  808.         {
  809.             GfxEdit_EncodeRP2_HashUpdateByte(cs, src, hash, hrov);
  810.             cs++;
  811.         }
  812.     }
  813.  
  814.     mr=cs-cs0;
  815.     while(mr>128)
  816.     {
  817.         k=(mr/8)-1;
  818.         if(k>511)
  819.             k=511;
  820.         tag=0x3F|(k<<7);
  821.         *ct++=(tag>>0)&255;
  822.         *ct++=(tag>>8)&255;
  823.         j=(k+1)*8;
  824.         memcpy(ct, cs0, j);
  825.         ct+=j; cs0+=j;
  826.         mr=cs-cs0;
  827.     }
  828.  
  829.     while(mr>=8)
  830.     {
  831.         k=(mr/8)-1;
  832.         if(k>15)
  833.             k=15;
  834.         *ct++=0x07|(k<<4);
  835.         j=(k+1)*8;
  836.         memcpy(ct, cs0, j);
  837.         ct+=j; cs0+=j;
  838.         mr=cs-cs0;
  839.     }
  840.    
  841.     while(mr>0)
  842.     {
  843.         k=mr;
  844.         if(k>3)
  845.             k=3;
  846.         *ct++=0x1F|(k<<6);
  847.         memcpy(ct, cs0, k);
  848.         ct+=k; cs0+=k;
  849.         mr=cs-cs0;
  850.     }
  851.    
  852.     *ct++=0x1F;
  853.     return(ct-dst);
  854. }
  855.  
  856. int GfxEdit_EncodeRP2Test(byte *dst, byte *src, int dsz, int ssz)
  857. {
  858.     byte *tptr;
  859.     int csz, tsz;
  860.     int i;
  861.    
  862.     tptr=malloc(ssz+1024);
  863.    
  864.     csz=GfxEdit_EncodeRP2(dst, src, dsz, ssz);
  865.     tsz=GfxEdit_DecodeRP2(tptr, dst, ssz+256, csz);
  866.    
  867.     if(tsz!=ssz)
  868.     {
  869.         __debugbreak();
  870.     }
  871.    
  872.     for(i=0; i<ssz; i++)
  873.         if(tptr[i]!=src[i])
  874.             break;
  875.    
  876.     if(i<ssz)
  877.     {
  878.         __debugbreak();
  879.     }
  880.    
  881.     free(tptr);
  882.     return(csz);
  883. }
  884.  
Advertisement
Add Comment
Please, Sign In to add comment