uncompressing a QFS file */
| 144 | |
| 145 | /* uncompressing a QFS file */ |
| 146 | unsigned char *uncompress_data(unsigned char *inbuf,int *buflen) |
| 147 | { |
| 148 | unsigned char *outbuf; |
| 149 | unsigned char packcode; |
| 150 | int a,b,c,len,offset; |
| 151 | int inlen,outlen,inpos,outpos; |
| 152 | |
| 153 | /* length of data */ |
| 154 | inlen=*buflen; |
| 155 | outlen=(inbuf[2]<<16)+(inbuf[3]<<8)+inbuf[4]; |
| 156 | outbuf=malloc(outlen); |
| 157 | if (outbuf==NULL) { printf("Insufficient memory.\n"); abandon_ship(); } |
| 158 | |
| 159 | /* position in file */ |
| 160 | if (inbuf[0]&0x01) inpos=8; else inpos=5; |
| 161 | outpos=0; |
| 162 | |
| 163 | /* main decoding loop */ |
| 164 | while ((inpos<inlen)&&(inbuf[inpos]<0xFC)) |
| 165 | { |
| 166 | packcode=inbuf[inpos]; |
| 167 | a=inbuf[inpos+1]; |
| 168 | b=inbuf[inpos+2]; |
| 169 | |
| 170 | if (!(packcode&0x80)) { |
| 171 | len=packcode&3; |
| 172 | mmemcpy(outbuf+outpos,inbuf+inpos+2,len); |
| 173 | inpos+=len+2; |
| 174 | outpos+=len; |
| 175 | len=((packcode&0x1c)>>2)+3; |
| 176 | offset=((packcode>>5)<<8)+a+1; |
| 177 | mmemcpy(outbuf+outpos,outbuf+outpos-offset,len); |
| 178 | outpos+=len; |
| 179 | } |
| 180 | else if (!(packcode&0x40)) { |
| 181 | len=(a>>6)&3; |
| 182 | mmemcpy(outbuf+outpos,inbuf+inpos+3,len); |
| 183 | inpos+=len+3; |
| 184 | outpos+=len; |
| 185 | len=(packcode&0x3f)+4; |
| 186 | offset=(a&0x3f)*256+b+1; |
| 187 | mmemcpy(outbuf+outpos,outbuf+outpos-offset,len); |
| 188 | outpos+=len; |
| 189 | } |
| 190 | else if (!(packcode&0x20)) { |
| 191 | c=inbuf[inpos+3]; |
| 192 | len=packcode&3; |
| 193 | mmemcpy(outbuf+outpos,inbuf+inpos+4,len); |
| 194 | inpos+=len+4; |
| 195 | outpos+=len; |
| 196 | len=((packcode>>2)&3)*256+c+5; |
| 197 | offset=((packcode&0x10)<<12)+256*a+b+1; |
| 198 | mmemcpy(outbuf+outpos,outbuf+outpos-offset,len); |
| 199 | outpos+=len; |
| 200 | } |
| 201 | else { |
| 202 | len=(packcode&0x1f)*4+4; |
| 203 | mmemcpy(outbuf+outpos,inbuf+inpos+1,len); |
no test coverage detected