diff --git a/iguana/exchanges/LP_commands.c b/iguana/exchanges/LP_commands.c index 76a665f8f..179e335b5 100644 --- a/iguana/exchanges/LP_commands.c +++ b/iguana/exchanges/LP_commands.c @@ -160,6 +160,7 @@ bot_stop(botid)\n\ bot_pause(botid)\n\ instantdex_deposit(weeks, amount, broadcast=1)\n\ instantdex_claim()\n\ +jpg(srcfile, destfile, power2=7, passphrase, data="")\n\ \"}")); //sell(base, rel, price, basevolume, timeout=10, duration=3600)\n\ @@ -226,6 +227,10 @@ instantdex_claim()\n\ } return(clonestr("{\"error\":\"cant find KMD\"}")); } + else if ( strcmp(method,"jpg") == 0 ) + { + return(LP_jpg(jstr(argjson,"srcfile"),jstr(argjson,"destfile"),jint(argjson,"power2"),jstr(argjson,"passphrase"),jstr(argjson,"data"),jint(argjson,"required"))); + } /*else if ( strcmp(method,"sendmessage") == 0 ) { if ( jobj(argjson,"method2") == 0 ) diff --git a/iguana/exchanges/LP_privkey.c b/iguana/exchanges/LP_privkey.c index c828e8a12..342ef0bc9 100644 --- a/iguana/exchanges/LP_privkey.c +++ b/iguana/exchanges/LP_privkey.c @@ -392,3 +392,183 @@ void LP_privkey_tests() } printf("%d privkeys checked\n",i); } + + +// from https://github.com/owencm/C-Steganography-Framework +#include "../../crypto777/jpeg/cdjpeg.h" // Common decls for compressing and decompressing jpegs + +int32_t LP_jpg_process(int32_t *capacityp,char *inputfname,char *outputfname,uint8_t *decoded,uint8_t *data,int32_t required,int32_t power2,char *passphrase) +{ + struct jpeg_decompress_struct inputinfo; + struct jpeg_compress_struct outputinfo; + struct jpeg_error_mgr jerr; + jvirt_barray_ptr *coef_arrays; + JDIMENSION i,compnum,rownum,blocknum; + JBLOCKARRAY coef_buffers[MAX_COMPONENTS]; + JBLOCKARRAY row_ptrs[MAX_COMPONENTS]; + FILE *input_file,*output_file; int32_t val,modified,emit,totalrows,limit; + if ( power2 < 0 || power2 > 16 ) + power2 = 4; + limit = 1; + while ( power2 > 0 ) + { + limit <<= 1; + power2--; + } + if ((input_file = fopen(inputfname, READ_BINARY)) == NULL) { + fprintf(stderr, "Can't open %s\n", inputfname); + exit(EXIT_FAILURE); + } + // Initialize the JPEG compression and decompression objects with default error handling + inputinfo.err = jpeg_std_error(&jerr); + jpeg_create_decompress(&inputinfo); + // Specify data source for decompression and recompression + jpeg_stdio_src(&inputinfo, input_file); + (void) jpeg_read_header(&inputinfo, TRUE); + for (compnum=0; compnummem->alloc_barray)((j_common_ptr)&inputinfo,JPOOL_IMAGE,inputinfo.comp_info[compnum].width_in_blocks,inputinfo.comp_info[compnum].height_in_blocks); + coef_arrays = jpeg_read_coefficients(&inputinfo); + // Copy DCT coeffs to a new array + int num_components = inputinfo.num_components; + size_t block_row_size[num_components]; + int width_in_blocks[num_components]; + int height_in_blocks[num_components]; + *capacityp = modified = emit = totalrows = 0; + if ( decoded != 0 ) + memset(decoded,0,required/8+1); + for (compnum=0; compnummem->access_virt_barray)((j_common_ptr)&inputinfo,coef_arrays[compnum],rownum,(JDIMENSION)1,FALSE); + for (blocknum=0; blocknum power2 ) + { + if ( decoded != 0 && (val & 1) != 0 && *capacityp < required ) + decoded[*capacityp >> 3] |= (1 << (*capacityp & 7)); + (*capacityp)++; + } + coef_buffers[compnum][rownum][blocknum][i] = val; + } + } + } + } + printf("capacity %d required.%d\n",*capacityp,required); + if ( *capacityp > required && outputfname != 0 && outputfname[0] != 0 ) + { + if ((output_file = fopen(outputfname, WRITE_BINARY)) == NULL) { + fprintf(stderr, "Can't open %s\n", outputfname); + exit(EXIT_FAILURE); + } + outputinfo.err = jpeg_std_error(&jerr); + jpeg_create_compress(&outputinfo); + jpeg_stdio_dest(&outputinfo, output_file); + jpeg_copy_critical_parameters(&inputinfo,&outputinfo); + // Print out or modify DCT coefficients + for (compnum=0; compnum power2 ) + { + val &= ~1; + if ( (data[emit >> 3] & (1 << (emit&7))) != 0 ) + val |= 1; + emit++; + } + coef_buffers[compnum][rownum][blocknum][i] = val; + //printf("%i,", coef_buffers[compnum][rownum][blocknum][i]); + } + } + } + } + //printf("\n\n"); + + /* Output the new DCT coeffs to a JPEG file */ + modified = 0; + for (compnum=0; compnummem->access_virt_barray)((j_common_ptr)&outputinfo,coef_arrays[compnum],rownum,(JDIMENSION)1,TRUE); + if ( memcmp(row_ptrs[compnum][0][0],coef_buffers[compnum][rownum][0],block_row_size[compnum]) != 0 ) + { + memcpy(row_ptrs[compnum][0][0],coef_buffers[compnum][rownum][0],block_row_size[compnum]); + modified++; + } + totalrows++; + } + } + // Write to the output file + jpeg_write_coefficients(&outputinfo, coef_arrays); + // Finish compression and release memory + jpeg_finish_compress(&outputinfo); + jpeg_destroy_compress(&outputinfo); + fclose(output_file); + } + jpeg_finish_decompress(&inputinfo); + jpeg_destroy_decompress(&inputinfo); + fclose(input_file); + if ( modified != 0 ) + { + printf("New DCT coefficients successfully written to %s, capacity %d modifiedrows.%d/%d emit.%d\n",outputfname,*capacityp,modified,totalrows,emit); + } + return(modified); +} + +char *LP_jpg(char *srcfile,char *destfile,int32_t power2,char *passphrase,char *datastr,int32_t required) +{ + cJSON *retjson; int32_t len=0,modified,capacity; char *decodedstr; uint8_t *data=0,*decoded=0; + if ( srcfile != 0 && srcfile[0] != 0 ) + { + retjson = cJSON_CreateObject(); + jaddstr(retjson,"result","success"); + if ( datastr != 0 && datastr[0] != 0 ) + { + if ( (len= is_hexstr(datastr,0)) > 0 ) + { + len >>= 1; + data = calloc(1,len); + decode_hex(data,len,datastr); + required = len * 8; + } + } + if ( required > 0 ) + decoded = calloc(1,len); + modified = LP_jpg_process(&capacity,srcfile,destfile,decoded,data,required,power2,passphrase); + jaddnum(retjson,"modifiedrows",modified); + if ( modified != 0 ) + jaddstr(retjson,"outputfile",destfile); + jaddnum(retjson,"power2",power2); + jaddnum(retjson,"capacity",capacity); + jaddnum(retjson,"required",required); + if ( decoded != 0 ) + { + decodedstr = calloc(1,len*2+1); + init_hexbytes_noT(decodedstr,decoded,len); + jaddstr(retjson,"decoded",decodedstr); + free(decodedstr); + free(decoded); + } + if ( data != 0 ) + free(data); + return(jprint(retjson,1)); + } else return(clonestr("{\"error\":\"no source file error\"}")); +} + + + +