开发者

BZip2 unzipping data that isn't a file without getting errors?

开发者 https://www.devze.com 2023-03-17 17:28 出处:网络
So I have this code that makes a series of bytes, but then zips it with bzip2. How could I unzip them? Plain(right-click) unzipping gives me corruption, probably because there are no file beginnings o

So I have this code that makes a series of bytes, but then zips it with bzip2. How could I unzip them? Plain(right-click) unzipping gives me corruption, probably because there are no file beginnings or ends. It needs to be done in some programming language, preferrably C#, C, C++, Java or Python. Also, I'd need to read that binary data in the unzipped stream. I'd appreciate any help.

This is the code, it fills an array and compresses it with BZ2_bzBuffToBuffCompress at the end:

void *build_save(int *size, int x0, int y0, int w, int h,
         unsigned char bmap[YRES/CELL][XRES/CELL], 
         float fvx[YRES/CELL][XRES/CELL], 
         float fvy[YRES/CELL][XRES/CELL], sign signs[MAXSIGNS],
         void* partsptr)
{
  unsigned char *d=calloc(1,3*(XRES/CELL)*(YRES/CELL)+(XRES*YRES)*15+MAXSIGNS*262), *c;
  int i,j,x,y,p=0,*m=calloc(XRES*YRES, sizeof(int));
  int bx0=x0/CELL, by0=y0/CELL, bw=(w+CELL-1)/CELL, bh=(h+CELL-1)/CELL;
  particle *parts = partsptr;

  // normalize coordinates
  x0 = bx0*CELL;
  y0 = by0*CELL;
  w = bw *CELL;
  h = bh *CELL;

  // save the required air state
  for (y=by0; y<by0+bh; y++)
    for (x=bx0; x<bx0+bw; x++)
      d[p++] = bmap[y][x];
  for (y=by0; y<by0+bh; y++)
    for (x=bx0; x<bx0+bw; x++)
      if (bmap[y][x]==WL_FAN||bmap[y][x]==4){
    i = (int)(fvx[y][x]*64.0f+127.5f);
      if (i<0) i=0;
      if (i>255) i=255;
      d[p++] = i;
      }
  for (y=by0; y<by0+bh; y++)
    for (x=bx0; x<bx0+bw; x++)
      if (bmap[y][x]==WL_FAN||bmap[y][x]==4){
    i = (int)(fvy[y][x]*64.0f+127.5f);
    if (i<0) i=0;
    if (i>255) i=255;
    d[p++] = i;
      }

  // save the particle map
  for (i=0; i<NPART; i++)
    if (parts[i].type) {
    x = (int)(parts[i].x+0.5f);
    y = (int)(parts[i].y+0.5f);
    if (x>=x0 && x<x0+w && y>=y0 && y<y0+h) {
      if (!m[(x-x0)+(y-y0)*w] ||
          parts[m[(x-x0)+(y-y0)*w]-1].type == PT_PHOT ||
          parts[m[(x-x0)+(y-y0)*w]-1].type == PT_NEUT)
        m[(x-x0)+(y-y0)*w] = i+1;
    }
    }
  for (j=0; j<w*h; j++) {
    i = m[j];
    if (i)
      d[p++] = parts[i-1].type;
    else
      d[p++] = 0;
  }

  // save particle properties
  for (j=0; j<w*h; j++){
    i = m[j];
    if (i)
      {
    i--;
    x = (int)(parts[i].vx*16.0f+127.5f);
    y = (int)(parts[i].vy*16.0f+127.5f);
    if (x<0) x=0;
    if (x>255) x=255;
    if (y<0) y=0;
    if (y>255) y=255;
    d[p++] = x;
    d[p++] = y;
      }
  }
  for (j=0; j<w*h; j++){
    i = m[j];
    if (i) {
      //Everybody loves a 16bit int
      //d[p++] = (parts[i-1].life+3)/4;
      int ttlife = (int)parts[i-1].life;
      d[p++] = ((ttlife&0xFF00)>>8);
      d[p++] = (ttlife&0x00FF);
    }
  }
  for (j=0; j<w*h; j++){
    i = m[j];
    if (i) {
      //Now saving tmp!
      //d[p++] = (parts[i-1].life+3)/4;
      int tttmp = (int)parts[i-1].tmp;
      d[p++] = ((tttmp&0xFF00)>>8);
      d[p++] = (tttmp&0x00FF);
        }
  }
  for (j=0; j<w*h; j++){
    i = m[j];
    if (i) {
      //Save colour (ALPHA)
      d[p++] = (parts[i-1].dcolour&0xFF000000)>>24;
    }
  }
  for (j=0; j<w*h; j++){
    i = m[j];
    if (i) {
      //Save colour (RED)
      d[p++] = (parts[i-1].dcolour&0x00FF0000)>>16;
    }
  }
  for (j=0; j<w*h; j++){
    i = m[j];
    if (i) {
      //Save colour (GREEN)
      d[p++] = (parts[i-1].dcolour&0x0000FF00)>>8;
    }
  }
  for (j=0; j<w*h; j++){
    i = m[j];
    if (i) {
      //Save colour (BLUE)
          d[p++] = (parts[i-1].dcolour&0x000000FF);
    }
  }
  for (j=0; j<w*h; j++){
    i = m[j];
    if (i){
      // New Temperature saving uses a 16bit unsigned int for
      // temperatures, giving a precision of 1 degree versus 36 for the old
      // format
      int tttemp = (int)parts[i-1].temp;
      d[p++] = ((tttemp&0xFF00)>>8);
      d[p++] = (tttemp&0x00FF);
    }
  }
  for (j=0; j<w*h; j++) {
    i = m[j];
    if (i && (parts[i-1].type==PT_CLNE || parts[i-1].type==PT_PCLN || 
          parts[i-1].type==PT_BCLN || parts[i-1].type==PT_SPRK || 
          parts[i-1].type==PT_LAVA || parts[i-1].type==PT_PIPE))
      d[p++] = parts[i-1].ctype;
  }

  j = 0;
  for (i=0; i<MAXSIGNS开发者_如何学Go; i++)
    if (signs[i].text[0] &&
    signs[i].x>=x0 && signs[i].x<x0+w &&
    signs[i].y>=y0 && signs[i].y<y0+h)
      j++;
  d[p++] = j;
  for (i=0; i<MAXSIGNS; i++)
    if (signs[i].text[0] &&
    signs[i].x>=x0 && signs[i].x<x0+w &&
    signs[i].y>=y0 && signs[i].y<y0+h){
      d[p++] = (signs[i].x-x0);
      d[p++] = (signs[i].x-x0)>>8;
          d[p++] = (signs[i].y-y0);
      d[p++] = (signs[i].y-y0)>>8;
      d[p++] = signs[i].ju;
      x = strlen(signs[i].text);
      d[p++] = x;
      memcpy(d+p, signs[i].text, x);
      p+=x;
    }

  i = (p*101+99)/100 + 612;
  c = malloc(i);

  //New file header uses PSv, replacing fuC. This is to detect if the
  //client uses a new save format for temperatures
  //This creates a problem for old clients, that display and "corrupt"
  //error instead of a "newer version" error

  c[0] = 0x50; //0x66;
  c[1] = 0x53; //0x75;
  c[2] = 0x76; //0x43;
  c[3] = legacy_enable|((sys_pause<<1)&0x02)|((gravityMode<<2)&0x0C)|((airMode<<4)&0x70)|((ngrav_enable<<7)&0x80);
  c[4] = SAVE_VERSION;
  c[5] = CELL;
  c[6] = bw;
  c[7] = bh;
  c[8] = p;
  c[9] = p >> 8;
  c[10] = p >> 16;
  c[11] = p >> 24;

  i -= 12;

  if (BZ2_bzBuffToBuffCompress((char *)(c+12), (unsigned *)&i, (char *)d, p, 9, 0, 0) != BZ_OK){
    free(d);
    free(c);
    free(m);
    return NULL;
  }
  free(d);
  free(m);

  *size = i+12;
  return c;
}


You have to call the function BZ2_bzBuffToBuffDecompress from the libbzip2 library http://www.bzip.org/1.0.6/bzip2-1.0.6.tar.gz

Here is the documentation: http://www.bzip.org/1.0.3/html/util-fns.html

You would call that code somehow like this:

#include <malloc.h>


int size;
void *buf=build_save(&size, ... add all the parameters ... );

enum{DEST=100000};
char*dest=malloc(DEST);
BZ2_bzBuffToBuffDecompress( dest, 
                            DEST, //unsigned int* destLen,
                            buf+12, //char*         source,
                            size-12, //unsigned int  sourceLen,
                            int           small,
                            int           verbosity );

Where I realize that you didn't give enough information. Try to search for your source for a call to

BZ2_bzDecompressInit ( bz_stream *strm, int verbosity, int small );

You will need to know the parameters verbosity and small for the decompression.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号