Exemple #1
0
int pfm_readpfm_size(FILE *fp,
          int *cols, int *rows)
{
  char buffer[1024];
  pfmGeoRead_=0;
  if (pfmCommentRead_) free(pfmCommentRead_);
  pfmCommentRead_=0;
  pfmGeoSet_=0;
  pfmComment_=0;
  fp=check_compression(buffer,fp);
#ifdef DEBUG
  printf("pfm_readpfm_size: %s\n",buffer);
#endif
  if (!((buffer[0]=='F' && buffer[1]>='0' && buffer[1]<='7')
    || (buffer[0]=='P' && buffer[1]>='1' && buffer[1]<='6'))) {
    fprintf(stderr,"pfm_readpfm: Wrong fileformat! (F)\n");
    fp=stop_decompression(fp);
    return 0;
  }

  read_buffer(buffer,1023,fp);
  fgets(buffer,1023,fp);
  sscanf(buffer,"%d %d",cols,rows);
  fp=stop_decompression(fp);
  return 1;
}    
Exemple #2
0
/*
* The main procedure is similar to the main found in ARITH1E.C. It has
* to initialize the coder and the model. It then sits in a loop reading
* input symbols and encoding them. One difference is that every 256
* symbols a compression check is performed. If the compression ratio
* falls below 10%, a flush character is encoded. This flushes the encod
* ing model, and will cause the decoder to flush its model when the 
* file is being expanded. The second difference is that each symbol is
* repeatedly encoded until a successful encoding occurs. When trying to
* encode a character in a particular order, the model may have to
* transmit an ESCAPE character. If this is the case, the character has
* to be retransmitted using a lower order. This process repeats until a
* successful match is found of the symbol in a particular context.
* Usually this means going down no further than the order -1 model.
* However, the FLUSH and DONE symbols drop back to the order -2 model.
*
*/
void CompressFile(FILE *input,BIT_FILE *output,int argc,char *argv[])
{
 SYMBOL s;
 int c;
 int escaped;
 int flush = 0;
 long int text_count = 0;
 initialize_options( argc, argv );
 initialize_model();
 initialize_arithmetic_encoder();
 for ( ; ; ) {
 if ( ( ++text_count & 0x0ff ) == 0 )
 	flush = check_compression( input, output );
 if ( !flush )
 	c = getc( input );
 else
 	c = FLUSH;
 if ( c == EOF )
 	c = DONE;
 do {
	 escaped = convert_int_to_symbol( c, &s);
	 encode_symbol( output, &s );
 } while ( escaped );
 if ( c == DONE )
 	break;
 if ( c == FLUSH ) {
	 flush_model();
	 flush = 0;
 }
 update_model( c );
 add_character_to_model( c );
 }
 flush_arithmetic_encoder( output );
}
static int bmp_checking(const struct bmp_type* img, const unsigned int in_size, const unsigned int max_size)
{
    if (!check_version(img))
    {
	fprintf(stderr,"Wrong BMP version (stegobmp only supports BMPv3\n");
	return WRONG_VERSION_ERR;
    }

    if (in_size > max_size)
    {
	fprintf(stderr,"The chosen image is too small to contain the message (of size %i bytes whereas maximum file size usable with this image is %i bytes)\n",in_size,max_size);
	return TOO_SMALL_ERR;
    }

    if (!check_compression(img))
    {
	fprintf(stderr,"stegobmp doesn't support compressed bmp\n");
	return COMPRESSED_ERR;
    }

    return 0;
}
Exemple #4
0
void *pfm_readpfm_type(FILE *fp,
           int *cols,
           int *rows,
           float *minval,
           float *maxval,
           int storageType,
           PFMConvert *convFunc)
{
/*  int compressed;*/
  void *ret_val;
  char buffer[1024];
  char     *data=0;
  float    *floatbuffer=0;
  double   *doublebuffer=0;
  int      *intbuffer=0;
  uint16   *int16buffer=0;
  grey     *greybuffer=0;
  PFM3Byte *ppmbuffer=0;
  int       byte_order=BYTEORDER;
  int r,c;
  int type;
  int storage_size[]={
          sizeof(float),
          sizeof(signed int),
          sizeof(unsigned int),
          sizeof(sint16),
          sizeof(uint16),
          sizeof(grey),
          sizeof(unsigned char),
          sizeof(unsigned char),
          sizeof(double)
          };
  ConvertFunc* double2[]={
       double2float,
       double2sint,
       double2sint,
       double2uint16,
       double2uint16,
       0,0,0,
       double2double,
       0};
  ConvertFunc* float2[]={
       float2float,
       float2sint,
       float2sint,
       float2uint16,
       float2uint16,
       0,0,0,
       float2double,
       0};
  ConvertFunc* uint162[]={
        uint162float,
        uint162sint,
        uint162sint,
        uint162uint16,
        uint162uint16,
        0,0,0,
        uint162double,
        0};
  ConvertFunc* sint2[]={
      sint2float,
      sint2sint,
      sint2sint,
      sint2uint16,
      sint2uint16,
      0,0,0,
      sint2double,
      0};
  ConvertFunc* pgm2[]={
      pgm2float,
      pgm2sint,
      pgm2sint,
      pgm2uint16,
      pgm2uint16,
      pgm2pgm,
      0,0,
      pgm2double,
      0};
  ConvertFunc* pbm2[]={
  0,0,0,0,0,0,0,0,0,0
  };

  memset(buffer, 0, 1024);
  pfmGeoRead_=0;
  if (pfmCommentRead_) free(pfmCommentRead_);
  pfmCommentRead_=0;
  pfmGeoSet_=0;
  fp=check_compression(buffer,fp);
  
#ifdef DEBUG
  printf("pfm_readpfm: %s\n",buffer);
#endif
  switch (buffer[0]) {
  case 'F':
    switch (buffer[1]) {
    case '0':
      type=PFM_FLOAT_ASCII;
      break;
    case '1':
      type=PFM_INT_ASCII;
      break;
    case '2':
      type=PFM_INT16_ASCII;
      break;
    case '3':
      type=PFM_DOUBLE_ASCII;
      break;
    case '4':
      type=PFM_FLOAT_BIN;
      break;
    case '5':
      type=PFM_INT_BIN;
      break;
    case '6':
      type=PFM_INT16_BIN;
      break;
    case '7':
      type=PFM_DOUBLE_BIN;
      break;
    default:
      fprintf(stderr,"pfm_readpfm: Wrong fileformat!\n");
      ret_val=0;
      goto exit_read_pfm;
    }
    break;
  case 'P':
    switch (buffer[1]) {
    case '1':
      type=PFM_PBM_ASCII;
      break;
    case '2':
      type=PFM_PGM_ASCII;
      break;
    case '3':
      type=PFM_PPM_ASCII;
      break;
    case '4':
      type=PFM_PBM_BIN;
      break;
    case '5':
      type=PFM_PGM_BIN;
      break;
    case '6':
      type=PFM_PPM_BIN;
      break;
    default:
      fprintf(stderr,"pfm_readpfm: Wrong fileformat!\n");
      ret_val=0;
      goto exit_read_pfm;
    }
    break;
  default:
    {
      fprintf(stderr,"pfm_readpfm: Wrong fileformat!\n");
      ret_val=0;
      goto exit_read_pfm;
    }
  }
  if ((type>=PFM_FLOAT_BIN) && (type<=PFM_DOUBLE_BIN))
    {
      read_buffer(buffer,1023,fp);
#ifdef DEBUG
      printf("pfm_readpfm: %s\n",buffer);
#endif
      if (buffer[0] == 'L')  {
        byte_order=PFM_LittleEndian;
      }
      else {
        byte_order=PFM_BigEndian;
      }
    }
  read_buffer(buffer,1023,fp);
#ifdef DEBUG
  printf("pfm_readpfm: %s\n",buffer);
#endif
  sscanf(buffer,"%d %d",cols,rows);
  read_buffer(buffer,1023,fp);
#ifdef DEBUG
  printf("pfm_readpfm: %s\n",buffer);
#endif
  pfm_mult=0.0;
  pfm_offset=0.0;
  if (sscanf(buffer,"%f %f %f %f",minval,maxval,&pfm_mult,&pfm_offset)<2) {
    *maxval=*minval;
    *minval=0.0;
  }
  if (type==PFM_PGM_BIN && *maxval>255) {
    type=PFM_INT16_BIN;
    byte_order=PFM_BigEndian;
  }
  if (type==PFM_PGM_ASCII && *maxval>255 && *maxval<=65535) {
    type=PFM_INT16_ASCII;
    byte_order=PFM_BigEndian;
  }
  if (pfm_mult!=0.0) convFunc=StretchConvert;
#ifdef DEBUG
  printf("pfm_readpfm: cols=%d rows=%d min=%f max=%f byte_order=%s\n",
   *cols,*rows,*minval,*maxval,(byte_order==PFM_BigEndian ? "BE" : "LE"));
#endif
  if (type==PFM_PPM_BIN) {
    ppmbuffer=(PFM3Byte*)malloc(sizeof(PFM3Byte));
    ppmbuffer->r=(unsigned char*)calloc(*cols*(*rows),storage_size[storageType]);
    ppmbuffer->g=(unsigned char*)calloc(*cols*(*rows),storage_size[storageType]);
    ppmbuffer->b=(unsigned char*)calloc(*cols*(*rows),storage_size[storageType]);
    if (ppmbuffer && ppmbuffer->r && ppmbuffer->g && ppmbuffer->b)
      data=(void*)ppmbuffer;
  }
  else data =(void*)calloc(*cols*(*rows),storage_size[storageType]);

  if (!data)
    {
      fprintf(stderr,"pfm_readpfm: Out of memory while allocating input buffer!\n");
      ret_val=0;
      goto exit_read_pfm;
    }
  switch (type)
    {
    case PFM_FLOAT_ASCII:
      if (!float2[storageType]) {
        fprintf(stderr,"pfm_readpfm: conversion from float to type %d not implemented\n",storageType);
        ret_val=0;
        goto exit_read_pfm;
      }
      floatbuffer=(float*)calloc(*cols,sizeof(float));
      if (!floatbuffer)  {
        fprintf(stderr,"pfm_readpfm: Out of memory (temporary float buffer)!\n");
        ret_val=0;
        goto exit_read_pfm;
      }
      for (r=0; r<*rows; r++)  {
        for (c=0; c<*cols; c++) {
          fscanf(fp,"%f",&(floatbuffer[c]));
        }
        float2[storageType](&data[r*(*cols)*storage_size[storageType]],
                            floatbuffer,
                            *cols,
                            convFunc,
                            *minval,
                            *maxval);
      }
      free(floatbuffer);
      break;
    case PFM_FLOAT_BIN:
      if (!float2[storageType]) {
        fprintf(stderr,"pfm_readpfm: conversion from float to type %d not implemented\n",storageType);
        ret_val=0;
        goto exit_read_pfm;
      }
      floatbuffer=(float*)calloc(*cols,sizeof(float));
      if (!floatbuffer)  {
        fprintf(stderr,"pfm_readpfm: Out of memory (temporary float buffer)!\n");
        ret_val=0;
        goto exit_read_pfm;
      }
      for (r=0; r<*rows; r++) {
        fread(floatbuffer,sizeof(float),*cols,fp);
        swapfloat(floatbuffer,*cols,byte_order);
        float2[storageType](&data[r*(*cols)*storage_size[storageType]],
                            floatbuffer,
                            *cols,
                            convFunc,
                            *minval,
                            *maxval);
  
      }
      free(floatbuffer);
      break;      
    case PFM_DOUBLE_ASCII:
      if (!double2[storageType]) {
        fprintf(stderr,"pfm_readpfm: conversion from double to type %d not implemented\n",storageType);
        ret_val=0;
        goto exit_read_pfm;
      }
      doublebuffer=(double*)calloc(*cols,sizeof(double));
      if (!doublebuffer)  {
        fprintf(stderr,"pfm_readpfm: Out of memory (temporary double buffer)!\n");
        ret_val=0;
        goto exit_read_pfm;
      }
      for (r=0; r<*rows; r++)  {
        for (c=0; c<*cols; c++) {
          fscanf(fp,"%lf",&(doublebuffer[c]));
        }
        double2[storageType](&data[r*(*cols)*storage_size[storageType]],
                            doublebuffer,
                            *cols,
                            convFunc,
                            *minval,
                            *maxval);
      }
      free(doublebuffer);
      break;
    case PFM_DOUBLE_BIN:
      if (!double2[storageType]) {
        fprintf(stderr,"pfm_readpfm: conversion from double to type %d not implemented\n",storageType);
        ret_val=0;
        goto exit_read_pfm;
      }
      doublebuffer=(double*)calloc(*cols,sizeof(double));
      if (!doublebuffer)  {
        fprintf(stderr,"pfm_readpfm: Out of memory (temporary double buffer)!\n");
        ret_val=0;
        goto exit_read_pfm;
      }
      for (r=0; r<*rows; r++) {
        fread(doublebuffer,sizeof(double),*cols,fp);
        swapdouble(doublebuffer,*cols,byte_order);
        double2[storageType](&data[r*(*cols)*storage_size[storageType]],
                            doublebuffer,
                            *cols,
                            convFunc,
                            *minval,
                            *maxval);
  
      }
      free(doublebuffer);
      break;
    case PFM_INT_ASCII:
      
      if (!sint2[storageType]) {
        fprintf(stderr,"pfm_readpfm: conversion from int to type %d not implemented\n",storageType);
        ret_val=0;
        goto exit_read_pfm;
      }
      intbuffer =(int*)calloc(*cols,sizeof(int));
      if (!intbuffer)  {
        fprintf(stderr,"pfm_readpfm: Out of memory (temporary int buffer)!\n");
        ret_val=0;
        goto exit_read_pfm;
      }
      for (r=0; r<*rows; r++)  {
        for (c=0; c<*cols; c++) {
          fscanf(fp,"%d",&(intbuffer[c]));
        }
        sint2[storageType](&data[r*(*cols)*storage_size[storageType]],
                            intbuffer,
                            *cols,
                            convFunc,
                            *minval,
                            *maxval);

      }
      free(intbuffer);
      break;
    case PFM_INT_BIN:
      if (!sint2[storageType]) {
        fprintf(stderr,"pfm_readpfm: conversion from int to type %d not implemented\n",storageType);
        ret_val=0;
        goto exit_read_pfm;
      }
      intbuffer =(int*)calloc(*cols,sizeof(int));
      if (!intbuffer)  {
        fprintf(stderr,"pfm_readpfm: Out of memory (temporary int buffer)!\n");
        ret_val=0;
        goto exit_read_pfm;
      }
      for (r=0; r<*rows; r++)  {
        fread(intbuffer,sizeof(int),*cols,fp);
        swapint(intbuffer,*cols,byte_order);
        sint2[storageType](&data[r*(*cols)*storage_size[storageType]],
                          intbuffer,
                          *cols,
                          convFunc,
                          *minval,
                          *maxval);
      }
      free(intbuffer);
      break;
    case PFM_INT16_ASCII:
      if (!uint162[storageType]) {
        fprintf(stderr,"pfm_readpfm: conversion from int16 to type %d not implemented\n",storageType);
        ret_val=0;
        goto exit_read_pfm;
      }
      int16buffer =(uint16*)calloc(*cols,sizeof(uint16));
      if (!int16buffer)  {
        fprintf(stderr,"pfm_readpfm: Out of memory (temporary int16 buffer)!\n");
        ret_val=0;
        goto exit_read_pfm;
      }
      for (r=0; r<*rows; r++)  {
        for (c=0; c<*cols; c++) {
          fscanf(fp,"%hd",&(int16buffer[c])); /* "%d" -> "%hd" (T. Wiebesiek, 31.3.2005) */
        }
        uint162[storageType](&data[r*(*cols)*storage_size[storageType]],
                            int16buffer,
                            *cols,
                            convFunc,
                            *minval,
                            *maxval);

      }
      free(int16buffer);
      break;
    case PFM_INT16_BIN:
      if (!uint162[storageType]) {
        fprintf(stderr,"pfm_readpfm: conversion from int16 to type %d not implemented\n",storageType);
        ret_val=0;
        goto exit_read_pfm;
      }
      int16buffer =(uint16*)calloc(*cols,sizeof(uint16));
      if (!int16buffer)  {
        fprintf(stderr,"pfm_readpfm: Out of memory (temporary int16 buffer)!\n");
        ret_val=0;
        goto exit_read_pfm;
      }
      for (r=0; r<*rows; r++) {
        fread(int16buffer,sizeof(uint16),*cols,fp);
        swapint16(int16buffer,*cols,byte_order);
        uint162[storageType](&data[r*(*cols)*storage_size[storageType]],
                            int16buffer,
                            *cols,
                            convFunc,
                            *minval,
                            *maxval);
      }
      free(int16buffer);
      break;
    case PFM_PGM_ASCII:
      fprintf(stderr,"pfm_readpfm: PGM ASCII not implemented!\n");
      ret_val=0;
      goto exit_read_pfm;
      break;
    case PFM_PGM_BIN:
      if (!pgm2[storageType]) {
        fprintf(stderr,"pfm_readpfm: conversion from pgm to type %d not implemented\n",storageType);
        ret_val=0;
        goto exit_read_pfm;
      }
      greybuffer =(grey*)calloc(*cols,sizeof(grey));
      if (!greybuffer)  {
        fprintf(stderr,"pfm_readpfm: Out of memory (temporary pgm buffer)!\n");
        ret_val=0;
        goto exit_read_pfm;
      }
      for (r=0; r<*rows; r++) {
        fread(greybuffer,sizeof(grey),*cols,fp);
        pgm2[storageType](&data[r*(*cols)*storage_size[storageType]],
                            greybuffer,
                            *cols,
                            convFunc,
                            *minval,
                            *maxval);
      }
      free(greybuffer);
      break;
    case PFM_PBM_ASCII:
      fprintf(stderr,"pfm_readpfm: PBM ASCII not implented!\n");
      ret_val=0;
      goto exit_read_pfm;
      break;
    case PFM_PBM_BIN:
      fprintf(stderr,"pfm_readpfm: PBM BIN not implented!\n");
      ret_val=0;
      goto exit_read_pfm;
      if (!pbm2[storageType]) {
        fprintf(stderr,"pfm_readpfm: conversion from pgm to type %d not implemented\n",storageType);
        ret_val=0;
        goto exit_read_pfm;
      }
      greybuffer =(grey*)calloc(*cols,sizeof(grey));
      if (!greybuffer)  {
        fprintf(stderr,"pfm_readpfm: Out of memory (temporary pgm buffer)!\n");
        ret_val=0;
        goto exit_read_pfm;
      }
      for (r=0; r<*rows; r++) {
        fread(greybuffer,sizeof(grey),*cols,fp);
        pgm2[storageType](&data[r*(*cols)*storage_size[storageType]],
                            greybuffer,
                            *cols,
                            convFunc,
                            *minval,
                            *maxval);
      }
      free(greybuffer);
      break;
    case PFM_PPM_BIN:
      pfm_read_ppm(fp,*cols,*rows,ppmbuffer);
#if 0
      if (!pgm2[storageType]) {
        fprintf(stderr,"pfm_readpfm: conversion from pgm to type %d not implemented\n",storageType);
        ret_val=0;
        goto exit_read_pfm;
      }
#endif      
      break;
    }
exit_read_pfm:
  if (compressed_) fp=stop_decompression(fp);
  return data;
}
Exemple #5
0
int pfm_readpfm_header(FILE *fp,
      int *cols, int *rows,
      float *minval, float *maxval,
      int *storageType)
{
  long filepos;
  char buffer[1024];
  int cols_, rows_;
  float minval_, maxval_;
  int type;
  int byte_order;
  pfmGeoRead_=0;
  if (pfmCommentRead_) free(pfmCommentRead_);
  pfmCommentRead_=0;
  pfmGeoSet_=0;
  pfmComment_=0;
  filepos=ftell(fp);
  fp=check_compression(buffer,fp);
#ifdef DEBUG
  printf("pfm_readpfm_header: %s\n",buffer);
#endif
  switch (buffer[0]) {
  case 'F':
    switch (buffer[1]) {
    case '0':
      type=PFM_FLOAT_ASCII;
      break;
    case '1':
      type=PFM_INT_ASCII;
      break;
    case '2':
      type=PFM_INT16_ASCII;
      break;
    case '3':
      type=PFM_DOUBLE_ASCII;
      break;
    case '4':
      type=PFM_FLOAT_BIN;
      break;
    case '5':
      type=PFM_INT_BIN;
      break;
    case '6':
      type=PFM_INT16_BIN;
      break;
    case '7':
      type=PFM_DOUBLE_BIN;
      break;
    default:
      fprintf(stderr,"pfm_readpfm: Wrong fileformat!\n");
      fp=stop_decompression(fp);
      fseek(fp,filepos,SEEK_SET);
      return 0;
    }
    break;
  case 'P':
    switch (buffer[1]) {
    case '1':
      type=PFM_PBM_ASCII;
      break;
    case '2':
      type=PFM_PGM_ASCII;
      break;
    case '3':
      type=PFM_PPM_ASCII;
      break;
    case '4':
      type=PFM_PBM_BIN;
#if 0      
      fprintf(stderr,"pfm_readpfm: PBM not supported by libpfm, use libpbm!\n");
#endif      
      fp=stop_decompression(fp);
       fseek(fp,filepos,SEEK_SET);
      return 0;
      break;
    case '5':
      type=PFM_PGM_BIN;
      break;
    case '6':
      type=PFM_PPM_BIN;
#if 0      
      fprintf(stderr,"pfm_readpfm: PPM not supported by libpfm, use libppm!\n");
      fp=stop_decompression(fp);
       fseek(fp,filepos,SEEK_SET);
      return 0;
#endif      
      break;
    default:
      fprintf(stderr,"pfm_readpfm: Wrong fileformat!\n");
      fp=stop_decompression(fp);
      fseek(fp,filepos,SEEK_SET);
      return 0;
    }
    break;
  default:
    fprintf(stderr,"pfm_readpfm: Wrong fileformat!\n");
    fp=stop_decompression(fp);
     fseek(fp,filepos,SEEK_SET);
    return 0;
  }
  if ((type>PFM_SINT16_ASCII) && (type<PFM_PGM_ASCII)) {
     read_buffer(buffer,1023,fp);
     if (buffer[0] == 'L') {
      byte_order=PFM_LittleEndian;
    }
     else {
      byte_order=PFM_BigEndian;
    }
  }
  read_buffer(buffer,1023,fp);
  sscanf(buffer,"%d %d",&cols_,&rows_);
  read_buffer(buffer,1023,fp);
  pfm_mult=1.0;
  pfm_offset=0.0;
  if (sscanf(buffer,"%f %f %f %f",&minval_,&maxval_,&pfm_mult,&pfm_offset)<2) {
    maxval_=minval_;
    minval_=0;
  }
  if (type==PFM_PGM_BIN && maxval_>255) type=PFM_INT16_BIN;
  if (type==PFM_PGM_ASCII && maxval_>255 && maxval_<=65535) type=PFM_INT16_ASCII;

  if (storageType) {
    switch (type) {
    case PFM_FLOAT_ASCII:
    case PFM_FLOAT_BIN:
      *storageType=PFM_FLOAT;
      break;
    case PFM_DOUBLE_ASCII:
    case PFM_DOUBLE_BIN:
      *storageType=PFM_DOUBLE;
      break;
    case PFM_INT_ASCII:
    case PFM_INT_BIN:
      *storageType=PFM_SINT;
      break;
    case PFM_INT16_ASCII:
    case PFM_INT16_BIN:
      *storageType=PFM_UINT16;
      break;
    case PFM_SINT16_ASCII:
    case PFM_SINT16_BIN:
      *storageType=PFM_SINT16;
      break;
    case PFM_PGM_ASCII:
    case PFM_PGM_BIN:
      *storageType=PFM_BYTE;
      break;
    case PFM_PBM_ASCII:
    case PFM_PBM_BIN:
      *storageType=PFM_BIT;
      break;
    case PFM_PPM_ASCII:
    case PFM_PPM_BIN:
      *storageType=PFM_3BYTE;
      break;
    }
#ifdef DEBUG
    printf("storageType=%d\n",*storageType);
#endif
  }
  if (minval) *minval=minval_;
  if (maxval) *maxval=maxval_;
  if (cols) *cols=cols_;
  if (rows) *rows=rows_;
#ifdef DEBUG
  printf("cols=%d, rows=%d, minval=%f, maxval=%f\n",cols_,rows_,minval_,maxval_);
#endif
  fp=stop_decompression(fp);
  fseek(fp,filepos,SEEK_SET);
  return 1;
}
static int lsbX_crypt_extract(FILE* image, FILE** msg_f, const char* name, const char *passwd, 
	const enum encrypt_type algo, const enum encrypt_block_type blk_algo,
	byte_reader *reader)
{
    uint8_t* encrypted_content;
    uint8_t* decrypted_content;
    struct bmp_type img;
    unsigned int offset = 0;
    uint32_t encrypted_size, msg_size, extension_size, decrypted_size;
    char* filename;

    /* header loading */
    load_img_header(image, &img);
    if (!check_version(&img) || !check_compression(&img)) {
	fprintf(stderr, "Format not supported (either the file is not a BMPv3 or it uses compression. Exiting.\n");
	return -1;
    }

    /* content loading */
    img.matrix = malloc(sizeof(uint8_t)*img.usable_size);
    load_img_matrix(image, &img);

    /*reading size*/
    if ((*reader)(&encrypted_size, sizeof(uint32_t), &img, &offset) != 0) {
	fprintf(stderr, "EOF was reached prematurely while attempting to read the embedded crypted file's size\n");
	free(img.matrix);
	return -1;
    }
    encrypted_size = ntohl(encrypted_size);
    if (encrypted_size > img.usable_size) {
	fprintf(stderr, "Fetched encrypted message size is bigger than carrier (%i <-> %i bytes)! Exiting.\n",encrypted_size,img.usable_size);
	free(img.matrix);
	return -1;
    }

    /*reading encrypted content*/
    encrypted_content = malloc(sizeof(uint8_t)*encrypted_size);
    decrypted_content = malloc(sizeof(uint8_t)*encrypted_size);
    
    if ((*reader)(encrypted_content, encrypted_size, &img, &offset) != 0) {
	fprintf(stderr, "EOF was reached prematurely while attempting to read the embedded crypted file's content\n");
	free(img.matrix);
	free(encrypted_content);
	free(decrypted_content);
	return -1;
    }

    /* freeing the matrix we won't need anymore */
    free(img.matrix);

    /* decrypting */
    if (decrypt(encrypted_content, encrypted_size, (unsigned char*) passwd, algo, blk_algo, decrypted_content, &decrypted_size) != 0)
	return -1;

    /* reading the actual data size */
    memcpy(&msg_size, decrypted_content, sizeof(uint32_t));
    msg_size = ntohl(msg_size);
    if (msg_size > decrypted_size - sizeof(uint32_t) - 1) { /* -1 because the extension must be at least a '\0' at the end */
	fprintf(stderr, "Message to be read bigger than decrypted chunk (%i <-> %i)! Exiting.\n", msg_size, decrypted_size);
	free(encrypted_content);
	free(decrypted_content);
	return -1;
    }


    /* reading extension */
    extension_size = decrypted_size - msg_size - sizeof(uint32_t);
    
    /* building the filename */
    filename = malloc(sizeof(uint8_t)*(strlen(name)+extension_size));
    strncpy(filename, name, strlen(name)+1);
    strncat(filename, (char*) &(decrypted_content[sizeof(uint32_t)+msg_size]), extension_size);

    /* writing to file */
    *msg_f = fopen(filename, "wb");
    fwrite((char*) &(decrypted_content[sizeof(uint32_t)]), sizeof(uint8_t), msg_size, *msg_f);

    free(encrypted_content);
    free(decrypted_content);
    free(filename);

    return 0;
}
static int lsbX_extract(FILE* image, FILE** msg_f, const char* name, byte_reader* reader, byte_counter* counter)
{
    char *msg, *extension;
    struct bmp_type img;
    uint32_t offset = 0;
    uint32_t msg_size;
    int extension_size;
    char* filename;

    /* header loading */
    load_img_header(image, &img);
    if (!check_version(&img) || !check_compression(&img)) {
	fprintf(stderr, "Format not supported (either the file is not a BMPv3 or it uses compression. Exiting.\n");
	return -1;
    }

    /* content loading */
    img.matrix = malloc(sizeof(uint8_t)*img.usable_size);
    load_img_matrix(image, &img);

    /*reading size*/
    if ((*reader)(&msg_size, sizeof(uint32_t), &img, &offset) != 0) {
	fprintf(stderr, "EOF was reached prematurely while attempting to read the embedded file's size\n");
	free(img.matrix);
	return -1;
    }
    msg_size = ntohl(msg_size);
    if (msg_size > img.usable_size) {
	fprintf(stderr, "Fetched message size is bigger than carrier (%i <-> %i bytes)! Exiting.\n",msg_size,img.usable_size);
	free(img.matrix);
	return -1;
    }

    /*reading content*/
    msg = calloc(msg_size, sizeof(uint8_t));
    if ((*reader)(msg, msg_size, &img, &offset) != 0) {
	fprintf(stderr, "EOF was reached prematurely while attempting to read the embedded file's content\n");
	free(img.matrix);
	free(msg);
	return -1;
    }

    /*reading extension*/
    if ((extension_size = (*counter)(&img, offset)) == -1) {
	fprintf(stderr, "EOF was reached prematurely while attempting to read the embedded file's extension.\n"
			"Continuing anyway but the result is likely to be unusable.\n");
	extension_size = 1;
	extension = malloc(sizeof(char));
	*extension = '\0';
    } else {
	extension = malloc(sizeof(char)*extension_size);
	(*reader)(extension, extension_size, &img, &offset); /* safe as we already checked the existence of the extension */
    }

    /* extension_size includes '\0' */
    filename = malloc(sizeof(char)*(extension_size+strlen(name)));
    strncpy(filename, name, strlen(name)+1);
    strncat(filename, extension, extension_size);
   
    *msg_f = fopen(filename, "wb");
    fwrite(msg, sizeof(uint8_t), msg_size, *msg_f);

    free(msg);
    free(filename);
    free(img.matrix);
    free(extension);

    return 0;
}