Hello!
I need some help again
I'm trying to decompress gzipped files using the qUncompress. As far I know, the difference between gzip-created file and the qCompressed one consists in:
1. Different headers. On my testing example (the same file that was compressed with gzip and qCompress) the header of qCompressed file = 10 bytes. But according to the source and docs, it must be only 4 bytes with the data length value. I'm confused.
2. Different tails. I know what gzip writes the 8-bytes trail (CRC32 and ISIZE). But what is 4 bytes of qCompressed trail?
Here is my testing code, that produces "Z_DATA_ERROR: Input data is corrupted" error:
Qt Code:
  1. //.gz file header
  2. typedef struct {
  3. quint8 id1;
  4. quint8 id2;
  5. quint8 cm;
  6. quint8 flg;
  7. float mtime;
  8. quint8 xfl;
  9. quint8 os;
  10. } t_gzip_header;
  11.  
  12. //bit flags
  13. #define gzip_hdr_FTEXT 0
  14. #define gzip_hdr_FHCRC 1
  15. #define gzip_hdr_FEXTRA 2
  16. #define gzip_hdr_FNAME 3
  17. #define gzip_hdr_FCOMMENT 4
  18.  
  19.  
  20. void rvln::test()
  21. {
  22. QFile file ("/home/test/test.cpp.gz");
  23.  
  24. if (! file.open (QFile::ReadOnly))
  25. return;
  26.  
  27. t_gzip_header gzip_header;
  28.  
  29. QDataStream s_in (&file);
  30.  
  31. //read the header to the struct instance:
  32. s_in >> gzip_header.id1;
  33. s_in >> gzip_header.id2;
  34. s_in >> gzip_header.cm;
  35. s_in >> gzip_header.flg;
  36. s_in >> gzip_header.mtime;
  37. s_in >> gzip_header.xfl;
  38. s_in >> gzip_header.os;
  39.  
  40. //read some additional chunks if flags are set
  41.  
  42. if (gzip_header.flg & (1 << gzip_hdr_FEXTRA))
  43. {
  44. quint16 size;
  45. s_in >> size;
  46. char *data = new char [size];
  47. s_in.readRawData (data,size);
  48. delete data;
  49. }
  50.  
  51. if (gzip_header.flg & (1 << gzip_hdr_FNAME))
  52. {
  53. qint8 c;
  54. QString original_fname;
  55. do
  56. {
  57. s_in >> c;
  58. original_fname += static_cast<char> (c);
  59. }
  60. while (c != 0);
  61.  
  62. qDebug() << original_fname;
  63. }
  64.  
  65.  
  66. if (gzip_header.flg & (1 << gzip_hdr_FCOMMENT))
  67. {
  68. qint8 c;
  69. QString comment;
  70. do
  71. {
  72. s_in >> c;
  73. comment += static_cast<char> (c);
  74. }
  75. while (c != 0);
  76.  
  77. qDebug() << comment;
  78. }
  79.  
  80. if (gzip_header.flg & (1 << gzip_hdr_FHCRC))
  81. {
  82. quint16 crc16;
  83. s_in >> crc16;
  84. }
  85.  
  86. //here is the stream reaches to the compressed data
  87. //so I read this data
  88. //and gzip's 8-bytes trail
  89. //to the buffer compressed_data
  90.  
  91. int len = file.size() - sizeof (t_gzip_header);
  92. char *compressed_data = new char [len];
  93. s_in.readRawData (compressed_data, len);
  94.  
  95. //the temporary array for compressed data
  96. //plus the 4-bytes header with the
  97. //uncompressed data length,
  98. //but how I can know the uncompressed data length
  99. //before uncompression?
  100.  
  101.  
  102. //trying to set the 4-bytes header
  103. //with the approx. uncompressed data length
  104.  
  105. len *= 10;
  106.  
  107. ta.resize(4);
  108.  
  109. ta[0] = (len & 0xff000000) >> 24;
  110. ta[1] = (len & 0x00ff0000) >> 16;
  111. ta[2] = (len & 0x0000ff00) >> 8;
  112. ta[3] = (len & 0x000000ff);
  113.  
  114. //add the compressed data to temp array
  115.  
  116. ta.append (compressed_data);
  117.  
  118. //remove the 8-byte gzip trail
  119.  
  120. ta.chop(8);
  121.  
  122. //trying to uncompress
  123.  
  124. QByteArray aucomp = qUncompress (ta);
  125.  
  126. //oops! Got "Z_DATA_ERROR: Input data is corrupted"
  127. //here
  128.  
  129. //and close the file in a deep sorrow
  130. file.close();
  131. }
To copy to clipboard, switch view to plain text mode 
P.S. all gzip-format related data is taken from http://www.gzip.org/zlib/rfc-gzip.html