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; }
/* * 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; }
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; }
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; }