Don't like ads? PRO users don't see any ads ;-)
Guest

Untitled

By: a guest on May 7th, 2012  |  syntax: C++  |  size: 5.90 KB  |  hits: 15  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. QByteArray MainWindow::decompress(QByteArray compressed_data)
  2. {
  3.         QByteArray raw_data,chunk_data;
  4.         int returnSize;
  5.         int successLoop;
  6.         switch(ui->compressionType->currentIndex())
  7.         {
  8.         case 2:
  9.         case 3:
  10.                 buffer_decompression->seek(0);
  11.                 buffer_decompression_out=compressed_data;
  12.                 raw_data=decompressor->readAll();
  13.                 if(raw_data.size()>0)
  14.                 {
  15.                         buffer_decompression->seek(0);
  16.                         buffer_decompression_out.resize(0);
  17.                         ui->statusBarApp->showMessage(tr("Decompressed data: %1").arg(raw_data.size()));
  18.                         return raw_data;
  19.                 }
  20.                 else
  21.                 {
  22.                         ui->statusBarApp->showMessage(tr("Error at decompressing: %1").arg(decompressor->errorString()));
  23.                         return compressed_data;
  24.                 }
  25.                 break;
  26.         case 0:
  27.         case 1:
  28.                 chunk_data.resize(ui->chunkSize->value());
  29.                 buffer_decompression_out.append(compressed_data);
  30.                 successLoop=0;
  31.                 do
  32.                 {
  33.                         returnSize=QLZ4_uncompress_unknownOutputSize(&buffer_decompression_out,&chunk_data,ui->chunkSize->value());
  34.                         if(returnSize==0 || returnSize==-2 || returnSize==-4)
  35.                                 break;
  36.                         if(returnSize<=0)
  37.                         {
  38.                                 ui->statusBarApp->showMessage(tr("Error at decompressing: %1").arg(returnSize));
  39.                                 return compressed_data;
  40.                         }
  41.                         chunk_data.resize(returnSize);
  42.                         raw_data+=chunk_data;
  43.                         successLoop++;
  44.                 } while(returnSize>0 && buffer_decompression_out.size()>0);
  45.                 if(buffer_decompression_out.size()>0)
  46.                         ui->statusBarApp->showMessage(tr("block decompressed: %1, remaining compressed data: %2").arg(successLoop).arg(buffer_decompression_out.size()));
  47.                 else
  48.                         ui->statusBarApp->showMessage(tr("block decompressed: %1").arg(successLoop));
  49.                 return raw_data;
  50.                 break;
  51.         default:
  52.         break;
  53.         }
  54.         return compressed_data;
  55. }
  56.  
  57. //**************************************
  58. // Constants
  59. //**************************************
  60. #define COPYLENGTH 8
  61. #define ML_BITS 4
  62. #define ML_MASK ((1U<<ML_BITS)-1)
  63. #define RUN_BITS (8-ML_BITS)
  64. #define RUN_MASK ((1U<<RUN_BITS)-1)
  65.  
  66. //**************************************
  67. // Basic Types
  68. //**************************************
  69. typedef struct _U16_S { quint16 v; } U16_S;
  70. typedef struct _U32_S { quint32 v; } U32_S;
  71. typedef struct _U64_S { quint64 v; } U64_S;
  72.  
  73. #define A64(x) (((U64_S *)(x))->v)
  74. #define A32(x) (((U32_S *)(x))->v)
  75. #define A16(x) (((U16_S *)(x))->v)
  76.  
  77. //**************************************
  78. // Architecture-specific macros
  79. //**************************************
  80. #if LZ4_ARCH64  // 64-bit
  81. #define STEPSIZE 8
  82. #define UARCH U64
  83. #define AARCH A64
  84. #define LZ4_COPYSTEP(s,d)               A64(d) = A64(s); d+=8; s+=8;
  85. #define LZ4_COPYPACKET(s,d)             LZ4_COPYSTEP(s,d)
  86. #define LZ4_SECURECOPY(s,d,e)   if (d<e) LZ4_WILDCOPY(s,d,e)
  87. #define HTYPE U32
  88. #define INITBASE(base)                  const quint8* const base = ip
  89. #else           // 32-bit
  90. #define STEPSIZE 4
  91. #define UARCH U32
  92. #define AARCH A32
  93. #define LZ4_COPYSTEP(s,d)               A32(d) = A32(s); d+=4; s+=4;
  94. #define LZ4_COPYPACKET(s,d)             LZ4_COPYSTEP(s,d); LZ4_COPYSTEP(s,d);
  95. #define LZ4_SECURECOPY                  LZ4_WILDCOPY
  96. #define HTYPE const quint8*
  97. #define INITBASE(base)                  const int base = 0
  98. #endif
  99.  
  100. //**************************************
  101. // Macros
  102. //**************************************
  103. #define LZ4_WILDCOPY(s,d,e)             do { LZ4_COPYPACKET(s,d) } while (d<e);
  104.  
  105. #if (defined(LZ4_BIG_ENDIAN) && !defined(BIG_ENDIAN_NATIVE_BUT_INCOMPATIBLE))
  106. #define LZ4_READ_LITTLEENDIAN_16(d,s,p) { U16 v = A16(p); v = bswap16(v); d = (s) - v; }
  107. #define LZ4_WRITE_LITTLEENDIAN_16(p,i) { U16 v = (U16)(i); v = bswap16(v); A16(p) = v; p+=2; }
  108. #else           // Little Endian
  109. #define LZ4_READ_LITTLEENDIAN_16(d,s,p) { d = (s) - A16(p); }
  110. #define LZ4_WRITE_LITTLEENDIAN_16(p,v) { A16(p) = v; p+=2; }
  111. #endif
  112.  
  113. int QLZ4_uncompress_unknownOutputSize(QByteArray *source,
  114.                                 QByteArray *destination,
  115.                                 int maxOutputSize)
  116. {
  117.         // Local Variables
  118.         const quint8* ip = (const quint8*) source->data();
  119.         const quint8* const iend = ip + source->size();
  120.         const quint8* ref;
  121.  
  122.         quint8* op = (quint8*) destination->data();
  123.         quint8* base_op = (quint8*) destination->data();
  124.         quint8* const oend = op + maxOutputSize;
  125.         quint8* cpy;
  126.  
  127.         size_t dec[] ={0, 3, 2, 3, 0, 0, 0, 0};
  128.  
  129.         quint8 token;
  130.         int length;
  131.  
  132.         // Main Loop
  133.         while (ip<iend)
  134.         {
  135.                 // get runlength
  136.                 token = *ip++;
  137.                 if ((length=(token>>ML_BITS)) == RUN_MASK) { int s=255; while ((ip<iend) && (s==255)) { s=*ip++; length += s; } }
  138.  
  139.                 // copy literals
  140.                 cpy = op+length;
  141.                 if ((cpy>oend-COPYLENGTH) || (ip+length>iend-COPYLENGTH))
  142.                 {
  143.                         if (cpy > oend)
  144.                                 return -1;
  145.                         if (ip+length > iend)
  146.                                 return -2;
  147.                         memcpy(op, ip, length);
  148.                         op += length;
  149.                         ip += length;
  150.                         //the remaining copy is of other packet
  151.                         /*if (ip<iend)
  152.                                 return -3;*/
  153.                         break;    // Necessarily EOF, due to parsing restrictions
  154.                 }
  155.                 do { LZ4_COPYPACKET(ip,op) } while (op<cpy);
  156.                 ip -= (op-cpy); op = cpy;
  157.  
  158.                 // get offset
  159.                 LZ4_READ_LITTLEENDIAN_16(ref,cpy,ip); ip+=2;
  160.                 if (ref<base_op)
  161.                         return -4;
  162.  
  163.                 // get matchlength
  164.                 if ((length=(token&ML_MASK)) == ML_MASK) { while (ip<iend) { int s = *ip++; length +=s; if (s==255) continue; break; } }
  165.  
  166.                 // copy repeated sequence
  167.                 if(__builtin_expect (((op-ref<STEPSIZE) != 0),0))
  168.                                 //(expect(, 0))
  169.                 {
  170. #if LZ4_ARCH64
  171.                         size_t dec2table[]={0, 0, 0, -1, 0, 1, 2, 3};
  172.                         size_t dec2 = dec2table[op-ref];
  173. #else
  174.                         const int dec2 = 0;
  175. #endif
  176.                         *op++ = *ref++;
  177.                         *op++ = *ref++;
  178.                         *op++ = *ref++;
  179.                         *op++ = *ref++;
  180.                         ref -= dec[op-ref];
  181.                         A32(op)=A32(ref); op += STEPSIZE-4;
  182.                         ref -= dec2;
  183.                 } else { LZ4_COPYSTEP(ref,op); }
  184.                 cpy = op + length - (STEPSIZE-4);
  185.                 if (cpy>oend-COPYLENGTH)
  186.                 {
  187.                         if (cpy > oend)
  188.                                 return -5;
  189.                         LZ4_SECURECOPY(ref, op, (oend-COPYLENGTH));
  190.                         while(op<cpy) *op++=*ref++;
  191.                         op=cpy;
  192.                         if (op == oend) break;    // Check EOF (should never happen, since last 5 bytes are supposed to be literals)
  193.                         continue;
  194.                 }
  195.                 LZ4_SECURECOPY(ref, op, cpy);
  196.                 op=cpy;         // correction
  197.         }
  198.  
  199.         // end of decoding
  200.         destination->resize((int)(op-base_op));
  201.         source->remove(0,(int)(ip-(const quint8*)source->data()));
  202.         return destination->size();
  203. }