37 changed files with 18 additions and 4291 deletions
@ -1,6 +1,3 @@
@@ -1,6 +1,3 @@
|
||||
[submodule "source/cxxopts"] |
||||
path = src/cxxopts |
||||
url = https://github.com/jarro2783/cxxopts.git |
||||
[submodule "src/PortLibCpp"] |
||||
path = src/PortLibCpp |
||||
url = https://git.teknik.io/suhrke/PortLibCpp.git |
||||
[submodule "lib/PortLibC"] |
||||
path = lib/PortLibC |
||||
url = https://git.teknik.io/suhrke/PortLibC.git |
||||
|
@ -1,18 +1,17 @@
@@ -1,18 +1,17 @@
|
||||
EX=paperback-cli |
||||
SDIR=./src |
||||
SDIR=src |
||||
BZDIR=lib/BZLIB |
||||
AESDIR=lib/AES |
||||
CC=g++ |
||||
PORTDIR=$(SDIR)/PortLibCpp/src |
||||
CFLAGS=-std=c++11 -I"$(SDIR)" -I"$(PORTDIR)" -I"$(SDIR)/cxxopts/include" -I"$(SDIR)/AES" -I"$(SDIR)/BZLIB" |
||||
PORTDIR=lib/PortLibC/src |
||||
CFLAGS=-std=c++11 -I"include" -I"$(PORTDIR)" -I"lib/cxxopts/include" -I"lib/AES" -I"lib/BZLIB" |
||||
|
||||
all: main |
||||
|
||||
main: $(SDIR)/main.cpp $(SDIR)/Printer.cpp $(SDIR)/Scanner.cpp $(SDIR)/Fileproc.cpp $(SDIR)/Decoder.cpp $(SDIR)/Fileproc.cpp $(SDIR)/Crc16.cpp $(SDIR)/Ecc.cpp $(SDIR)/BZLIB/bz_lib.cpp $(SDIR)/BZLIB/bz_blocksort.cpp $(SDIR)/BZLIB/bz_compress.cpp $(SDIR)/BZLIB/bz_crctable.cpp $(SDIR)/BZLIB/bz_decompress.cpp $(SDIR)/BZLIB/bz_huffman.cpp $(SDIR)/BZLIB/bz_randtable.cpp $(SDIR)/AES/ae_aes.cpp $(PORTDIR)/FileAttributes.cpp #$(SDIR)/Decoder.cpp
|
||||
main: $(SDIR)/main.cpp $(SDIR)/Printer.cpp $(SDIR)/Scanner.cpp $(SDIR)/Fileproc.cpp $(SDIR)/Decoder.cpp $(SDIR)/Fileproc.cpp $(SDIR)/Crc16.cpp $(SDIR)/Ecc.cpp $(BZDIR)/bz_lib.cpp $(BZDIR)/bz_blocksort.cpp $(BZDIR)/bz_compress.cpp $(BZDIR)/bz_crctable.cpp $(BZDIR)/bz_decompress.cpp $(BZDIR)/bz_huffman.cpp $(BZDIR)/bz_randtable.cpp $(AESDIR)/ae_aes.cpp $(PORTDIR)/FileAttributes.c |
||||
$(CC) $^ $(CFLAGS) -o $(EX) |
||||
|
||||
msys: $(SDIR)/main.cpp $(SDIR)/Printer.cpp $(SDIR)/Fileproc.cpp $(SDIR)/Decoder.cpp |
||||
$(CC) $^ $(CFLAGS) -o $(EX) -mwin32 |
||||
|
||||
|
||||
clean: |
||||
rm $(EX) #*.o *.log |
||||
rm $(EX) *.o *.log |
||||
|
||||
|
@ -0,0 +1 @@
@@ -0,0 +1 @@
|
||||
Subproject commit 8196bd4c38a255020ad53f1cca305fafe49dc1d6 |
@ -1 +0,0 @@
@@ -1 +0,0 @@
|
||||
Subproject commit 5ec94e2bfeaa1cf4c2f7e807697c923e3d8aeb14 |
@ -1,88 +0,0 @@
@@ -1,88 +0,0 @@
|
||||
/*
|
||||
* ===================================================================================== |
||||
* |
||||
* Filename: Bitmap.h |
||||
* |
||||
* Description: Bitmap structs and defines |
||||
* |
||||
* Version: 1.0 |
||||
* Created: 07/26/2017 09:38:18 PM |
||||
* Revision: none |
||||
* Compiler: gcc |
||||
* |
||||
* Author: suhrke@teknik.io |
||||
* |
||||
* ===================================================================================== |
||||
*/ |
||||
|
||||
#ifndef BITMAP_H |
||||
#define BITMAP_H |
||||
|
||||
#include <cstdint> |
||||
|
||||
#define BI_RGB 0 //bitmap value for uncompressed color data
|
||||
#define CHAR_BM 19778 |
||||
|
||||
|
||||
|
||||
//Padding specific to compiler - must account for padded bfType
|
||||
// and little-endian order when overlaying struct on buffer
|
||||
typedef struct OverlayBitmapFileHeader { |
||||
uint16_t bfType = CHAR_BM; //filetype, must be 'BM'
|
||||
uint8_t bfSize0; |
||||
uint8_t bfSize1; |
||||
|
||||
uint8_t bfSize2; |
||||
uint8_t bfSize3; |
||||
uint16_t bfReserved1 = 0; |
||||
|
||||
uint16_t bfReserved2 = 0; |
||||
uint8_t bfOffBits0; |
||||
uint8_t bfOffBits1; |
||||
|
||||
uint8_t bfOffBits2; |
||||
uint8_t bfOffBits3; |
||||
|
||||
} OverlayBitmapFileHeader; |
||||
|
||||
typedef struct BITMAPFILEHEADER { |
||||
uint16_t bfType = CHAR_BM;//filetype, must be 'BM'
|
||||
uint32_t bfSize; //size in bytes of bitmap file
|
||||
uint16_t bfReserved1 = 0; //unused, except to keep alignment
|
||||
uint16_t bfReserved2 = 0; //unused, except to keep alignment
|
||||
uint32_t bfOffBits; //offset in bytes from beginning of
|
||||
// BITMAPFILEHEADER to the bitmap bits
|
||||
} BITMAPFILEHEADER; |
||||
|
||||
typedef struct BITMAPINFOHEADER { |
||||
uint32_t biSize; //# of bytes in struct
|
||||
int32_t biWidth; //width of bitmap in pixels
|
||||
int32_t biHeight; //height of bitmap in pixels
|
||||
uint16_t biPlanes = 1; //# of planes for target device
|
||||
uint16_t biBitCount; //bitmap, bits per pixel
|
||||
uint32_t biCompression; //bitmap, type of compression
|
||||
uint32_t biSizeImage; //size of image, in bytes
|
||||
// 0 if BI_RGB
|
||||
int32_t biXPelsPerMeter; //horizontal resolution of target device
|
||||
int32_t biYPelsPerMeter; //vertical resolution of target device
|
||||
uint32_t biClrUsed; //# of color indices in color table
|
||||
// if 0, bitmap uses max # of colors that
|
||||
// correspond to biBitCount
|
||||
uint32_t biClrImportant; //# of color indices required for displaying bitmap
|
||||
} BITMAPINFOHEADER; |
||||
|
||||
typedef struct RGBQUAD { |
||||
unsigned char rgbBlue; |
||||
unsigned char rgbGreen; |
||||
unsigned char rgbRed; |
||||
unsigned char rgbReserved = 0; |
||||
} RGBQUAD; |
||||
|
||||
typedef struct BITMAPINFO { |
||||
BITMAPINFOHEADER bmiHeader; |
||||
RGBQUAD bmiColors[1]; |
||||
} BITMAPINFO; |
||||
|
||||
|
||||
#endif //BITMAP_H
|
||||
|
@ -1,76 +0,0 @@
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
* ===================================================================================== |
||||
* |
||||
* Filename: Crc16.h |
||||
* |
||||
* Description: Cyclic redundancy checks for file integrity |
||||
* |
||||
* Version: 1.2 |
||||
* Created: 07/26/2017 08:42:11 PM |
||||
* Revision: none |
||||
* Compiler: gcc |
||||
* |
||||
* Author: Oleh Yuschuk |
||||
* Modified By: scuti@teknik.io |
||||
* |
||||
* ===================================================================================== |
||||
*/ |
||||
|
||||
#ifndef CRC16_H |
||||
#define CRC16_H |
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// Fast 16-bit CRC (CCITT version). //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
const unsigned int crctab[256] = { |
||||
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, |
||||
0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, |
||||
0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, |
||||
0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, |
||||
0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485, |
||||
0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D, |
||||
0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4, |
||||
0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, |
||||
0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, |
||||
0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, |
||||
0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, |
||||
0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, |
||||
0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, |
||||
0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, |
||||
0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70, |
||||
0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78, |
||||
0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F, |
||||
0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067, |
||||
0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, |
||||
0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, |
||||
0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, |
||||
0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, |
||||
0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C, |
||||
0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634, |
||||
0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, |
||||
0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3, |
||||
0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, |
||||
0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, |
||||
0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, |
||||
0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, |
||||
0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, |
||||
0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0 |
||||
}; |
||||
|
||||
inline unsigned short Crc16(unsigned char *data,int length) { |
||||
unsigned int crc; |
||||
for (crc=0; length>0; length--) |
||||
crc=((crc<<8)^crctab[((crc>>8)^(*data++))]) & 0xFFFF; |
||||
return (unsigned short)crc; |
||||
}; |
||||
|
||||
|
||||
|
||||
|
||||
#endif //CRC16_H
|
||||
|
@ -1,167 +0,0 @@
@@ -1,167 +0,0 @@
|
||||
/*
|
||||
* ===================================================================================== |
||||
* |
||||
* Filename: Decoder.h |
||||
* |
||||
* Description: Decode paperbak data obtained from bitmap file |
||||
* |
||||
* Version: 1.2 |
||||
* Created: 07/26/2017 05:43:57 AM |
||||
* Revision: none |
||||
* Compiler: gcc |
||||
* |
||||
* Author: Oleh Yuschuk |
||||
* Modified By: suhrke@teknik.io |
||||
* |
||||
* ===================================================================================== |
||||
*/ |
||||
|
||||
#ifndef DECODER_H |
||||
#define DECODER_H |
||||
|
||||
#include <string> |
||||
#include "Global.h" |
||||
|
||||
#define M_BEST 0x00000001 // Search for best possible quality
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct t_procdata { // Descriptor of processed data
|
||||
int step; // Next data processing step (0 - idle)
|
||||
int mode; // Set of M_xxx
|
||||
uchar *data; // Pointer to bitmap
|
||||
int sizex; // X bitmap size, pixels
|
||||
int sizey; // Y bitmap size, pixels
|
||||
int gridxmin; // Rought X grid limits, pixels
|
||||
int gridxmax; // Rought X grid limits, pixels
|
||||
int gridymin; // Rought Y grid limits, pixels
|
||||
int gridymax; // Rought Y grid limits, pixels
|
||||
int searchx0; // X grid search limits, pixels
|
||||
int searchx1; // X grid search limits, pixels
|
||||
int searchy0; // Y grid search limits, pixels
|
||||
int searchy1; // Y grid search limits, pixels
|
||||
int cmean; // Mean grid intensity (0..255)
|
||||
int cmin; // Minimal and maximal grid intensity
|
||||
int cmax; // Minimal and maximal grid intensity
|
||||
float sharpfactor; // Estimated sharpness correction factor
|
||||
float xpeak; // Base X grid line, pixels
|
||||
float xstep; // X grid step, pixels
|
||||
float xangle; // X tilt, radians
|
||||
float ypeak; // Base Y grid line, pixels
|
||||
float ystep; // Y grid step, pixels
|
||||
float yangle; // Y tilt, radians
|
||||
float blockborder; // Relative width of border around block
|
||||
int bufdx; // Dimensions of block buffers, pixels
|
||||
int bufdy; // Dimensions of block buffers, pixels
|
||||
uchar *buf1; // Rotated and sharpened block
|
||||
uchar *buf2; // Rotated and sharpened block
|
||||
int *bufx; // Block grid data finders
|
||||
int *bufy; // Block grid data finders
|
||||
uchar *unsharp; // Either buf1 or buf2
|
||||
uchar *sharp; // Either buf1 or buf2
|
||||
float blockxpeak; // Exact block position in unsharp
|
||||
float blockypeak; // Exact block position in unsharp
|
||||
float blockxstep; // Exact block dimensions in unsharp
|
||||
float blockystep; // Exact block dimensions in unsharp
|
||||
int nposx; // Number of blocks to scan in X
|
||||
int nposy; // Number of blocks to scan in X
|
||||
int posx; // Next block to scan
|
||||
int posy; // Next block to scan
|
||||
t_data uncorrected; // Data before ECC for block display
|
||||
t_block *blocklist; // List of blocks recognized on page
|
||||
t_superblock superblock; // Page header
|
||||
int maxdotsize; // Maximal size of the data dot, pixels
|
||||
int orientation; // Data orientation (-1: unknown)
|
||||
int ngood; // Page statistics: good blocks
|
||||
int nbad; // Page statistics: bad blocks
|
||||
int nsuper; // Page statistics: good superblocks
|
||||
int nrestored; // Page statistics: restored bytes
|
||||
} t_procdata; |
||||
|
||||
|
||||
inline void print_procdata(t_procdata &pd) { |
||||
using namespace std; |
||||
cout << "==============================================================================" << endl; |
||||
cout << "step: " << pd.step << endl; |
||||
cout << "mode: " << pd.mode << endl; |
||||
cout << "*data: " << *pd.data << endl; |
||||
cout << "sizex: " << pd.sizex << endl; |
||||
cout << "sizey: " << pd.sizey << endl; |
||||
cout << "gridxmin: " << pd.gridxmin << endl; |
||||
cout << "gridxmax: " << pd.gridxmax << endl; |
||||
cout << "gridymin: " << pd.gridymin << endl; |
||||
cout << "gridymax: " << pd.gridymax << endl; |
||||
cout << "searchx0: " << pd.searchx0 << endl; |
||||
cout << "searchx1: " << pd.searchx1 << endl; |
||||
cout << "searchy0: " << pd.searchy0 << endl; |
||||
cout << "searchy1: " << pd.searchy1 << endl; |
||||
cout << "cmean: " << pd.cmean << endl; |
||||
cout << "cmin: " << pd.cmin << endl; |
||||
cout << "cmax: " << pd.cmax << endl; |
||||
cout << "sharpfactor: " << pd.sharpfactor << endl; |
||||
cout << "xpeak: " << pd.xpeak << endl; |
||||
cout << "xstep: " << pd.xstep << endl; |
||||
cout << "xangle: " << pd.xangle << endl; |
||||
cout << "ypeak: " << pd.ypeak << endl; |
||||
cout << "ystep: " << pd.ystep << endl; |
||||
cout << "yangle: " << pd.yangle << endl; |
||||
cout << "blockborder: " << pd.blockborder << endl; |
||||
cout << "bufdx: " << pd.bufdx << endl; |
||||
cout << "bufdy: " << pd.bufdy << endl; |
||||
cout << "*buf1: " << *pd.buf1 << endl; |
||||
cout << "*buf2: " << *pd.buf2 << endl; |
||||
cout << "*bufx: " << *pd.bufx << endl; |
||||
cout << "*bufy: " << *pd.bufy << endl; |
||||
if( pd.unsharp == NULL ) |
||||
cout << "*unsharp is NULL " << endl; |
||||
else |
||||
cout << "*unsharp: " << *pd.unsharp << endl; |
||||
if( pd.sharp == NULL ) |
||||
cout << "*sharp is NULL" << endl; |
||||
else |
||||
cout << "*sharp: " << *pd.sharp << endl; |
||||
cout << "blockxpeak: " << pd.blockxpeak << endl; |
||||
cout << "blockypeak: " << pd.blockypeak << endl; |
||||
cout << "blockxstep: " << pd.blockxstep << endl; |
||||
cout << "blockystep: " << pd.blockystep << endl; |
||||
cout << "nposx: " << pd.nposx << endl; |
||||
cout << "nposy: " << pd.nposy << endl; |
||||
cout << "posx: " << pd.posx << endl; |
||||
cout << "posy: " << pd.posy << endl; |
||||
print_data(pd.uncorrected); |
||||
cout << "*blocklist is non-NULL: " << (pd.blocklist!=0) << endl; |
||||
print_superblock(pd.superblock); |
||||
cout << "maxdotsize: " << pd.maxdotsize << endl; |
||||
cout << "orientation: " << pd.orientation << endl; |
||||
cout << "ngood: " << pd.ngood << endl; |
||||
cout << "nbad: " << pd.nbad << endl; |
||||
cout << "nsuper: " << pd.nsuper << endl; |
||||
cout << "nrestored: " << pd.nrestored << endl; |
||||
cout << "==============================================================================" << endl; |
||||
} |
||||
|
||||
|
||||
|
||||
//unique
|
||||
extern int orientation; // Orientation of bitmap (-1: unknown)
|
||||
//unique
|
||||
extern t_procdata procdata; // Descriptor of processed data
|
||||
|
||||
//void Nextdataprocessingstep(t_procdata *pdata);
|
||||
int Decodebitmap(const std::string &fileName); |
||||
int Getgridposition(t_procdata *pdata); |
||||
int Getgridintensity(t_procdata *pdata); |
||||
int Getxangle(t_procdata *pdata); |
||||
int Getyangle(t_procdata *pdata); |
||||
void Preparefordecoding(t_procdata *pdata); |
||||
void Decodenextblock(t_procdata *pdata); |
||||
void Finishdecoding(t_procdata *pdata); |
||||
void Freeprocdata(t_procdata *pdata); |
||||
void Startbitmapdecoding(t_procdata *pdata,uchar *data,int sizex,int sizey); |
||||
void Stopbitmapdecoding(t_procdata *pdata); |
||||
int Decodeblock(t_procdata *pdata,int posx,int posy,t_data *result); |
||||
int ProcessDIB(void *hdata,int offset); |
||||
|
||||
#endif //DECODER_H
|
||||
|
@ -1,260 +0,0 @@
@@ -1,260 +0,0 @@
|
||||
/*
|
||||
* ===================================================================================== |
||||
* |
||||
* Filename: Ecc.h |
||||
* |
||||
* Description: Reed-Solomon error correcting code data and functions |
||||
* |
||||
* Version: 1.2 |
||||
* Created: 07/26/2017 08:42:39 PM |
||||
* Revision: none |
||||
* Compiler: gcc |
||||
* |
||||
* Author: Oleh Yuschuk |
||||
* Modified By: scuti@teknik.io |
||||
* |
||||
* ===================================================================================== |
||||
*/ |
||||
|
||||
#ifndef ECC_H |
||||
#define ECC_H |
||||
|
||||
#include <string> |
||||
|
||||
typedef unsigned char uchar; |
||||
typedef unsigned int uint; |
||||
|
||||
|
||||
|
||||
|
||||
const uchar alpha[] = { |
||||
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, |
||||
0x87, 0x89, 0x95, 0xad, 0xdd, 0x3d, 0x7a, 0xf4, |
||||
0x6f, 0xde, 0x3b, 0x76, 0xec, 0x5f, 0xbe, 0xfb, |
||||
0x71, 0xe2, 0x43, 0x86, 0x8b, 0x91, 0xa5, 0xcd, |
||||
0x1d, 0x3a, 0x74, 0xe8, 0x57, 0xae, 0xdb, 0x31, |
||||
0x62, 0xc4, 0x0f, 0x1e, 0x3c, 0x78, 0xf0, 0x67, |
||||
0xce, 0x1b, 0x36, 0x6c, 0xd8, 0x37, 0x6e, 0xdc, |
||||
0x3f, 0x7e, 0xfc, 0x7f, 0xfe, 0x7b, 0xf6, 0x6b, |
||||
0xd6, 0x2b, 0x56, 0xac, 0xdf, 0x39, 0x72, 0xe4, |
||||
0x4f, 0x9e, 0xbb, 0xf1, 0x65, 0xca, 0x13, 0x26, |
||||
0x4c, 0x98, 0xb7, 0xe9, 0x55, 0xaa, 0xd3, 0x21, |
||||
0x42, 0x84, 0x8f, 0x99, 0xb5, 0xed, 0x5d, 0xba, |
||||
0xf3, 0x61, 0xc2, 0x03, 0x06, 0x0c, 0x18, 0x30, |
||||
0x60, 0xc0, 0x07, 0x0e, 0x1c, 0x38, 0x70, 0xe0, |
||||
0x47, 0x8e, 0x9b, 0xb1, 0xe5, 0x4d, 0x9a, 0xb3, |
||||
0xe1, 0x45, 0x8a, 0x93, 0xa1, 0xc5, 0x0d, 0x1a, |
||||
0x34, 0x68, 0xd0, 0x27, 0x4e, 0x9c, 0xbf, 0xf9, |
||||
0x75, 0xea, 0x53, 0xa6, 0xcb, 0x11, 0x22, 0x44, |
||||
0x88, 0x97, 0xa9, 0xd5, 0x2d, 0x5a, 0xb4, 0xef, |
||||
0x59, 0xb2, 0xe3, 0x41, 0x82, 0x83, 0x81, 0x85, |
||||
0x8d, 0x9d, 0xbd, 0xfd, 0x7d, 0xfa, 0x73, 0xe6, |
||||
0x4b, 0x96, 0xab, 0xd1, 0x25, 0x4a, 0x94, 0xaf, |
||||
0xd9, 0x35, 0x6a, 0xd4, 0x2f, 0x5e, 0xbc, 0xff, |
||||
0x79, 0xf2, 0x63, 0xc6, 0x0b, 0x16, 0x2c, 0x58, |
||||
0xb0, 0xe7, 0x49, 0x92, 0xa3, 0xc1, 0x05, 0x0a, |
||||
0x14, 0x28, 0x50, 0xa0, 0xc7, 0x09, 0x12, 0x24, |
||||
0x48, 0x90, 0xa7, 0xc9, 0x15, 0x2a, 0x54, 0xa8, |
||||
0xd7, 0x29, 0x52, 0xa4, 0xcf, 0x19, 0x32, 0x64, |
||||
0xc8, 0x17, 0x2e, 0x5c, 0xb8, 0xf7, 0x69, 0xd2, |
||||
0x23, 0x46, 0x8c, 0x9f, 0xb9, 0xf5, 0x6d, 0xda, |
||||
0x33, 0x66, 0xcc, 0x1f, 0x3e, 0x7c, 0xf8, 0x77, |
||||
0xee, 0x5b, 0xb6, 0xeb, 0x51, 0xa2, 0xc3, 0x00 |
||||
}; |
||||
|
||||
const uchar _index[] = { |
||||
255, 0, 1, 99, 2, 198, 100, 106, |
||||
3, 205, 199, 188, 101, 126, 107, 42, |
||||
4, 141, 206, 78, 200, 212, 189, 225, |
||||
102, 221, 127, 49, 108, 32, 43, 243, |
||||
5, 87, 142, 232, 207, 172, 79, 131, |
||||
201, 217, 213, 65, 190, 148, 226, 180, |
||||
103, 39, 222, 240, 128, 177, 50, 53, |
||||
109, 69, 33, 18, 44, 13, 244, 56, |
||||
6, 155, 88, 26, 143, 121, 233, 112, |
||||
208, 194, 173, 168, 80, 117, 132, 72, |
||||
202, 252, 218, 138, 214, 84, 66, 36, |
||||
191, 152, 149, 249, 227, 94, 181, 21, |
||||
104, 97, 40, 186, 223, 76, 241, 47, |
||||
129, 230, 178, 63, 51, 238, 54, 16, |
||||
110, 24, 70, 166, 34, 136, 19, 247, |
||||
45, 184, 14, 61, 245, 164, 57, 59, |
||||
7, 158, 156, 157, 89, 159, 27, 8, |
||||
144, 9, 122, 28, 234, 160, 113, 90, |
||||
209, 29, 195, 123, 174, 10, 169, 145, |
||||
81, 91, 118, 114, 133, 161, 73, 235, |
||||
203, 124, 253, 196, 219, 30, 139, 210, |
||||
215, 146, 85, 170, 67, 11, 37, 175, |
||||
192, 115, 153, 119, 150, 92, 250, 82, |
||||
228, 236, 95, 74, 182, 162, 22, 134, |
||||
105, 197, 98, 254, 41, 125, 187, 204, |
||||
224, 211, 77, 140, 242, 31, 48, 220, |
||||
130, 171, 231, 86, 179, 147, 64, 216, |
||||
52, 176, 239, 38, 55, 12, 17, 68, |
||||
111, 120, 25, 154, 71, 116, 167, 193, |
||||
35, 83, 137, 251, 20, 93, 248, 151, |
||||
46, 75, 185, 96, 15, 237, 62, 229, |
||||
246, 135, 165, 23, 58, 163, 60, 183 |
||||
}; |
||||
|
||||
const uchar poly[] = { |
||||
0, 249, 59, 66, 4, 43, 126, 251, |
||||
97, 30, 3, 213, 50, 66, 170, 5, |
||||
24, 5, 170, 66, 50, 213, 3, 30, |
||||
97, 251, 126, 43, 4, 66, 59, 249, |
||||
0 |
||||
}; |
||||
|
||||
|
||||
|
||||
inline void Encode8(uchar *data,uchar *bb,int pad) { |
||||
int i,j; |
||||
uchar feedback; |
||||
memset(bb,0,32); |
||||
for (i=0; i<223-pad; i++) { |
||||
feedback=_index[data[i]^bb[0]]; |
||||
if (feedback!=255) { |
||||
for (j=1; j<32; j++) { |
||||
bb[j]^=alpha[(feedback+poly[32-j])%255]; |
||||
}; |
||||
}; |
||||
memmove(bb,bb+1,31); |
||||
if (feedback!=255) |
||||
bb[31]=alpha[(feedback+poly[0])%255]; |
||||
else |
||||
bb[31]=0; |
||||
; |
||||
}; |
||||
}; |
||||
|
||||
|
||||
|
||||
inline int Decode8(uchar *data,int *eras_pos,int no_eras,int pad) { |
||||
int i,j,r,k,deg_lambda,el,deg_omega; |
||||
int syn_error,count; |
||||
uchar u,q,tmp,num1,num2,den,discr_r; |
||||
uchar lambda[33],s[32],b[33],t[33],omega[33]; |
||||
uchar root[32],reg[33],loc[32]; |
||||
for (i=0; i<32; i++) |
||||
s[i]=data[0]; |
||||
for (j=1; j<255-pad; j++) { |
||||
for (i=0; i<32; i++) { |
||||
if (s[i]==0) |
||||
s[i]=data[j]; |
||||
else |
||||
s[i]=data[j]^alpha[(_index[s[i]]+(112+i)*11)%255]; |
||||
; |
||||
}; |
||||
}; |
||||
syn_error=0; |
||||
for (i=0; i<32; i++) { |
||||
syn_error|=s[i]; |
||||
s[i]=_index[s[i]]; }; |
||||
if (syn_error==0) { |
||||
count=0; goto finish; }; |
||||
memset(lambda+1,0,32); |
||||
lambda[0]=1; |
||||
if (no_eras>0) { |
||||
lambda[1]=alpha[(11*(254-eras_pos[0]))%255]; |
||||
for (i=1; i<no_eras; i++) { |
||||
u=(uchar)((11*(254-eras_pos[i]))%255); |
||||
for (j=i+1; j>0; j--) { |
||||
tmp=_index[lambda[j-1]]; |
||||
if (tmp!=255) lambda[j]^=alpha[(u+tmp)%255]; |
||||
}; |
||||
}; |
||||
}; |
||||
for (i=0; i<33; i++) |
||||
b[i]=_index[lambda[i]]; |
||||
r=el=no_eras; |
||||
while (++r<=32) { |
||||
discr_r=0; |
||||
for (i=0; i<r; i++) { |
||||
if ((lambda[i]!=0) && (s[r-i-1]!=255)) { |
||||
discr_r^=alpha[(_index[lambda[i]]+s[r-i-1])%255]; |
||||
}; |
||||
}; |
||||
discr_r=_index[discr_r]; |
||||
if (discr_r==255) { |
||||
memmove(b+1,b,32); |
||||
b[0]=255; } |
||||
else { |
||||
t[0]=lambda[0]; |
||||
for (i=0; i<32; i++) { |
||||
if (b[i]!=255) |
||||
t[i+1]=lambda[i+1]^alpha[(discr_r+b[i])%255]; |
||||
else |
||||
t[i+1]=lambda[i+1]; |
||||
; |
||||
}; |
||||
if (2*el<=r+no_eras-1) { |
||||
el=r+no_eras-el; |
||||
for (i=0; i<=32; i++) |
||||
b[i]=(uchar)(lambda[i]==0?255:(_index[lambda[i]]-discr_r+255)%255); |
||||
; } |
||||
else { |
||||
memmove(b+1,b,32); |
||||
b[0]=255; }; |
||||
memcpy(lambda,t,33); |
||||
}; |
||||
}; |
||||
deg_lambda=0; |
||||
for (i=0; i<33; i++) { |
||||
lambda[i]=_index[lambda[i]]; |
||||
if (lambda[i]!=255) deg_lambda=i; }; |
||||
memcpy(reg+1,lambda+1,32); |
||||
count=0; |
||||
for (i=1,k=115; i<=255; i++,k=(k+116)%255) { |
||||
q=1; |
||||
for (j=deg_lambda; j>0; j--) { |
||||
if (reg[j]!=255) { |
||||
reg[j]=(uchar)((reg[j]+j)%255); |
||||
q^=alpha[reg[j]]; |
||||
}; |
||||
}; |
||||
if (q!=0) continue; |
||||
root[count]=(uchar)i; |
||||
loc[count]=(uchar)k; |
||||
if (++count==deg_lambda) break; |
||||
}; |
||||
if (deg_lambda!=count) { |
||||
count=-1; |
||||
goto finish; }; |
||||
deg_omega=deg_lambda-1; |
||||
for (i=0; i<=deg_omega; i++ ) { |
||||
tmp=0; |
||||
for (j=i; j>=0; j--) { |
||||
if ((s[i-j]!=255) && (lambda[j]!=255)) { |
||||
tmp^=alpha[(s[i-j]+lambda[j])%255]; |
||||
}; |
||||
}; |
||||
omega[i]=_index[tmp]; |
||||
}; |
||||
for (j=count-1; j>=0; j--) { |
||||
num1=0; |
||||
for (i=deg_omega; i>=0; i--) { |
||||
if (omega[i]!=255) { |
||||
num1^=alpha[(omega[i]+i*root[j])%255]; |
||||
}; |
||||
}; |
||||
num2=alpha[(root[j]*111+255)%255]; |
||||
den=0; |
||||
for (i=(deg_lambda<31?deg_lambda:31) & ~1; i>=0; i-=2) { |
||||
if (lambda[i+1]!=255) { |
||||
den^=alpha[(lambda[i+1]+i*root[j])%255]; |
||||
}; |
||||
}; |
||||
if (num1!=0 && loc[j]>=pad) { |
||||
data[loc[j]-pad]^=alpha[(_index[num1]+_index[num2]+255-_index[den])%255]; |
||||
}; |
||||
}; |
||||
finish: |
||||
if (eras_pos!=NULL) { |
||||
for (i=0; i<count; i++) eras_pos[i]=loc[i]; }; |
||||
return count; |
||||
}; |
||||
|
||||
|
||||
|
||||
#endif //ECC_H
|
||||
|
@ -1,430 +0,0 @@
@@ -1,430 +0,0 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// PaperBack -- high density backups on the plain paper //
|
||||
// //
|
||||
// Copyright (c) 2007 Oleh Yuschuk //
|
||||
// ollydbg at t-online de (set Subject to 'paperback' or be filtered out!) //
|
||||
// //
|
||||
// //
|
||||
// This file is part of PaperBack. //
|
||||
// //
|
||||
// Paperback is free software; you can redistribute it and/or modify it under //
|
||||
// the terms of the GNU General Public License as published by the Free //
|
||||
// Software Foundation; either version 3 of the License, or (at your option) //
|
||||
// any later version. //
|
||||
// //
|
||||
// PaperBack is distributed in the hope that it will be useful, but WITHOUT //
|
||||
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or //
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for //
|
||||
// more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU General Public License along //
|
||||
// with this program. If not, see <http://www.gnu.org/licenses/>. //
|
||||
// //
|
||||
// //
|
||||
// Note that bzip2 compression/decompression library, which is the part of //
|
||||
// this project, is covered by different license, which, in my opinion, is //
|
||||
// compatible with GPL. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <algorithm> |
||||
#include <cstring> |
||||
#include <math.h> |
||||
#include "Fileproc.h" |
||||
#include "Resource.h" |
||||
#ifdef _WIN32 |
||||
#include <windows.h> |
||||
#elif __linux__ |
||||
#include <cstdio> |
||||
#include <sys/stat.h> |
||||
#endif |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
t_fproc fproc; // extern
|
||||
char outfile[MAXPATH]; |
||||
|
||||
|
||||
// Clears descriptor of processed file
|
||||
void Closefproc() { |
||||
if (fproc.datavalid!=NULL) |
||||
free(fproc.datavalid); |
||||
if (fproc.data!=NULL) |
||||
free(fproc.data); |
||||
//memset(fproc+slot,0,sizeof(t_fproc));
|
||||
//Updatefileinfo(slot,fproc+slot); //GUI
|
||||
}; |
||||
|
||||
|
||||
|
||||
// Starts new decoded page. Returns non-negative index to table of processed
|
||||
// files on success or -1 on error.
|
||||
int Startnextpage(t_superblock *superblock) { |
||||
t_fproc tmp = {}; |
||||
t_fproc *pf = &tmp; |
||||
// initialize new descriptor.
|
||||
|
||||
// strnicmp no longer in standard C++
|
||||
std::string pfName(pf->name); |
||||
std::string superblockName(superblock->name); |
||||
std::transform(pfName.begin(), pfName.end(), |
||||
pfName.begin(), ::tolower); |
||||
std::transform(superblockName.begin(), superblockName.end(), |
||||
superblockName.begin(), ::tolower); |
||||
const char * cPfName = pfName.c_str(); |
||||
const char * cSuperblockName = superblockName.c_str(); |
||||
|
||||
#ifdef __linux__ |
||||
// instead of FILETIME comparision, use time_t
|
||||
double seconds = difftime(pf->modified, superblock->modified); |
||||
#endif |
||||
|
||||
if (strcmp(cPfName,cSuperblockName)==0 // same file name
|
||||
&& pf->mode==superblock->mode // same compression mode
|
||||
#ifdef _WIN32 |
||||
&& (pf->modified.dwLowDateTime!=superblock->modified.dwLowDateTime || |
||||
pf->modified.dwHighDateTime!=superblock->modified.dwHighDateTime) |
||||
// same timestamp
|
||||
#elif __linux__ |
||||
&& difftime > 0 // same timestamp
|
||||
#endif |
||||
&& pf->datasize==superblock->datasize // same compressed size
|
||||
&& pf->origsize!=superblock->origsize // same original size
|
||||
// File found. Check for the case of two backup copies printed with
|
||||
// different settings.
|
||||
&& pf->pagesize!=superblock->pagesize) |
||||
{ |
||||
pf->pagesize=0; |
||||
} |
||||
|
||||
|
||||
pf=&fproc; |
||||
memset(pf,0,sizeof(t_fproc)); |
||||
// Allocate block and recovery tables.
|
||||
pf->nblock=(superblock->datasize+NDATA-1)/NDATA; |
||||
pf->datavalid=(uchar *)calloc(pf->nblock, sizeof(uchar*)); |
||||
pf->data=(uchar *)calloc(pf->nblock*NDATA, sizeof(uchar*)); |
||||
if (pf->datavalid==NULL || pf->data==NULL) { |
||||
if (pf->datavalid!=NULL) free(pf->datavalid); |
||||
if (pf->data!=NULL) free(pf->data); |
||||
Reporterror("Low memory"); |
||||
return -1; }; |
||||
// Initialize remaining fields.
|
||||
memcpy(pf->name,superblock->name,64); |
||||
pf->modified=superblock->modified; |
||||
pf->attributes=superblock->attributes; |
||||
pf->filecrc=superblock->filecrc; |
||||
pf->datasize=superblock->datasize; |
||||
pf->pagesize=superblock->pagesize; |
||||
pf->origsize=superblock->origsize; |
||||
pf->mode=superblock->mode; |
||||
if (pf->pagesize>0) |
||||
pf->npages=(pf->datasize+pf->pagesize-1)/pf->pagesize; |
||||
else |
||||
pf->npages=0; |
||||
pf->ndata=0; |
||||
for (int i=0; i<pf->npages && i<8; i++) |
||||
pf->rempages[i]=i+1; |
||||
// Initialize statistics and declare descriptor as busy.
|
||||
pf->goodblocks=0; |
||||
pf->badblocks=0; |
||||
pf->restoredbytes=0; |
||||
pf->recoveredblocks=0; |
||||
pf->busy=1; |
||||
|
||||
// Invalidate page limits and report success.
|
||||
pf=&fproc; |
||||
pf->page=superblock->page; |
||||
pf->ngroup=superblock->ngroup; |
||||
pf->minpageaddr=0xFFFFFFFF; |
||||
pf->maxpageaddr=0; |
||||
//Updatefileinfo(slot,pf); //GUI
|
||||
return 0; |
||||
}; |
||||
|
||||
|
||||
|
||||
// Adds block recognized by decoder to file described by file descriptor with
|
||||
// specified index. Returns 0 on success and -1 on any error.
|
||||
int Addblock(t_block *block) { |
||||
int i,j; |
||||
t_fproc *pf; |
||||
pf=&fproc; |
||||
if (pf->busy==0) |
||||
return -1; // Index points to unused descriptor
|
||||
// Add block to descriptor.
|
||||
if (block->recsize==0) { |
||||
// Ordinary data block.
|
||||
i=block->addr/NDATA; |
||||
if ((ulong)(i*NDATA)!=block->addr) |
||||
return -1; // Invalid data alignment
|
||||
if (i>=pf->nblock) |
||||
return -1; // Data outside the data size
|
||||
if (pf->datavalid[i]!=1) { |
||||
memcpy(pf->data+block->addr,block->data,NDATA); |
||||
pf->datavalid[i]=1; // Valid data
|
||||
pf->ndata++; }; |
||||
pf->minpageaddr=std::min(pf->minpageaddr,block->addr); |
||||
pf->maxpageaddr=std::max(pf->maxpageaddr,block->addr+NDATA); } |
||||
else { |
||||
// Data recovery block. I write it to all free locations within the group.
|
||||
if (block->recsize!=(ulong)(pf->ngroup*NDATA)) |
||||
return -1; // Invalid recovery scope
|
||||
i=block->addr/block->recsize; |
||||
if (i*block->recsize!=block->addr) |
||||
return -1; // Invalid data alignment
|
||||
i=block->addr/NDATA; |
||||
for (j=i; j<i+pf->ngroup; j++) { |
||||
if (j>=pf->nblock) |
||||
return -1; // Data outside the data size
|
||||
if (pf->datavalid[j]!=0) continue; |
||||
memcpy(pf->data+j*NDATA,block->data,NDATA); |
||||
pf->datavalid[j]=2; }; // Valid recovery data
|
||||
pf->minpageaddr=std::min(pf->minpageaddr,block->addr); |
||||
pf->maxpageaddr=std::max(pf->maxpageaddr,block->addr+block->recsize); |
||||
}; |
||||
// Report success.
|
||||
return 0; |
||||
}; |
||||
|
||||
|
||||
|
||||
// Processes gathered data. Returns -1 on error, 0 if file is complete and
|
||||
// number of pages to scan if there is still missing data. In the last case,
|
||||
// fills list of several first remaining pages in file descriptor.
|
||||
int Finishpage(int ngood,int nbad,ulong nrestored) { |
||||
int i,j,r,rmin,rmax,nrec,irec,firstblock,nrempages; |
||||
uchar *pr,*pd; |
||||
t_fproc *pf; |
||||
pf=&fproc; |
||||
if (pf->busy==0) |
||||
return -1; // Index points to unused descriptor
|
||||
// Update statistics. Note that it grows also when the same page is scanned
|
||||
// repeatedly.
|
||||
pf->goodblocks+=ngood; |
||||
pf->badblocks+=nbad; |
||||
pf->restoredbytes+=nrestored; |
||||
// Restore bad blocks if corresponding recovery blocks are available (max. 1
|
||||
// per group).
|
||||
if (pf->ngroup>0) { |
||||
rmin=(pf->minpageaddr/(NDATA*pf->ngroup))*pf->ngroup; |
||||
rmax=(pf->maxpageaddr/(NDATA*pf->ngroup))*pf->ngroup; |
||||
// Walk groups of data on current page, one by one.
|
||||
for (r=rmin; r<=rmax; r+=pf->ngroup) { |
||||
if (r+pf->ngroup>pf->nblock) |
||||
break; // Inconsistent data
|
||||
// Count blocks with recovery data in the group.
|
||||
nrec=0; |
||||
for (i=r; i<r+pf->ngroup; i++) { |
||||
if (pf->datavalid[i]==2) { |
||||
nrec++; irec=i; |
||||
pf->datavalid[i]=0; // Prepare for next round
|
||||
}; |
||||
}; |
||||
if (nrec==1) { |
||||
// Exactly one block in group is missing, recovery is possible.
|
||||
pr=pf->data+irec*NDATA; |
||||
// Invert recovery data.
|
||||
for (j=0; j<NDATA; j++) *pr++^=0xFF; |
||||
// XOR recovery data with good data blocks.
|
||||
for (i=r; i<r+pf->ngroup; i++) { |
||||
if (i==irec) continue; |
||||
pr=pf->data+irec*NDATA; |
||||
pd=pf->data+i*NDATA; |
||||
for (j=0; j<NDATA; j++) { |
||||
*pr++^=*pd++; |
||||
}; |
||||
}; |
||||
pf->datavalid[irec]=1; |
||||
pf->recoveredblocks++; |
||||
pf->ndata++; |
||||
}; |
||||
}; |
||||
}; |
||||
// Check whether there are still bad blocks on the page.
|
||||
firstblock=(pf->page-1)*(pf->pagesize/NDATA); |
||||
for (j=firstblock; j<firstblock+pf->pagesize/NDATA && j<pf->nblock; j++) { |
||||
if (pf->datavalid[j]!=1) break; }; |
||||
if (j<firstblock+pf->pagesize/NDATA && j<pf->nblock) |
||||
Message("Unrecoverable errors on page, please scan it again",0); |
||||
else if (nbad>0) |
||||
Message("Page processed, all bad blocks successfully restored",0); |
||||
else |
||||
Message("Page processed",0); |
||||
// Calculate list of (partially) incomplete pages.
|
||||
nrempages=0; |
||||
if (pf->pagesize>0) { |
||||
for (i=0; i<pf->npages && nrempages<8; i++) { |
||||
firstblock=i*(pf->pagesize/NDATA); |
||||
for (j=firstblock; j<firstblock+pf->pagesize/NDATA && j<pf->nblock; j++) { |
||||
if (pf->datavalid[j]==1) |
||||
continue; |
||||
// Page incomplete.
|
||||
pf->rempages[nrempages++]=i+1; |
||||
break; |
||||
}; |
||||
}; |
||||
}; |
||||
if (nrempages<8) |
||||
pf->rempages[nrempages]=0; |
||||
//Updatefileinfo(slot,pf); //GUI
|
||||
/*if (pf->ndata==pf->nblock) {
|
||||
if (autosave==0) |
||||
Message("File restored. Press \"Save\" to save it to disk",0); |
||||
else { |
||||
Message("File complete",0); |
||||
Saverestoredfile(0); |
||||
}; |
||||
};*/ |
||||
if (pf->ndata != pf->nblock) { |
||||
Message("File complete",0); |
||||
Saverestoredfile(0); |
||||
}; |
||||
|
||||
return 0; ////////////////////////////////////////////////////////////////////
|
||||
}; |
||||
|
||||
|
||||
|
||||
// Saves file with specified index and closes file descriptor (if force is 1,
|
||||
// attempts to save data even if file is not yet complete). Returns 0 on
|
||||
// success and -1 on error.
|
||||
int Saverestoredfile(int force) { |
||||
int n,success; |
||||
ushort filecrc; |
||||
ulong length; |
||||
uchar *bufout,*data,*tempdata; |
||||
t_fproc *pf; |
||||
#ifdef _WIN32 |
||||
HANDLE hfile; |
||||
uint l; |
||||
#elif __linux__ |
||||
std::string hfile; |
||||
ulong l; |
||||
#endif |
||||
pf=&fproc; |
||||
if (pf->busy==0 || pf->nblock==0) |
||||
return -1; // Index points to unused descriptor
|
||||
if (pf->ndata!=pf->nblock && force==0) |
||||
return -1; // Still incomplete data
|
||||
Message("",0); |
||||
//aes_context ctx;
|
||||
// If data is encrypted, decrypt it to temporary buffer. Decryption in place
|
||||
// is possible, but the whole data would be lost if password is incorrect.
|
||||
/*if (pf->mode & PBM_ENCRYPTED) {
|
||||
if (pf->datasize & 0x0000000F) { |
||||
Reporterror("Encrypted data is not aligned"); |
||||
return -1; }; |
||||
if (Getpassword()!=0) |
||||
return -1; // User cancelled decryption
|
||||
tempdata=(uchar *)malloc(pf->datasize); |
||||
if (tempdata==NULL) { |
||||
Reporterror("Low memory, can't decrypt data"); |
||||
return -1; }; |
||||
n=strlen(password); |
||||
while (n<PASSLEN) password[n++]=0; |
||||
memset(&ctx,0,sizeof(ctx)); |
||||
aes_set_key(&ctx,(uchar *)password,256); |
||||
for (l=0; l<pf->datasize; l+=16) |
||||
aes_decrypt(&ctx,pf->data+l,tempdata+l); |
||||
filecrc=Crc16(tempdata,pf->datasize); |
||||
if (filecrc!=pf->filecrc) { |
||||
Reporterror("Invalid password, please try again"); |
||||
free(tempdata); |
||||
return -1; } |
||||
else { |
||||
free(pf->data); |
||||
pf->data=tempdata; |
||||
pf->mode&=~PBM_ENCRYPTED; |
||||
}; |
||||
}; */ |
||||
// If data is compressed, unpack it to temporary buffer.
|
||||
//if ((pf->mode & PBM_COMPRESSED)==0) {
|
||||
// Data is not compressed.
|
||||
data=pf->data; length=pf->origsize; |
||||
bufout=NULL; |
||||
//}
|
||||
/*else {
|
||||
// Data is compressed. Create temporary buffer.
|
||||
if (pf->origsize==0) |
||||
pf->origsize=pf->datasize*4; // Weak attempt to recover
|
||||
bufout=(uchar *)malloc(pf->origsize); |
||||
if (bufout==NULL) { |
||||
Reporterror("Low memory"); |
||||
return -1; }; |
||||
// Unpack data.
|
||||
length=pf->origsize; |
||||
success=BZ2_bzBuffToBuffDecompress((char *)bufout,(uint *)&length, |
||||
pf->data,pf->datasize,0,0); |
||||
if (success!=BZ_OK) { |
||||
free(bufout); |
||||
Reporterror("Unable to unpack data"); |
||||
return -1; }; |
||||
data=bufout; }; |
||||
// Ask user for file name.
|
||||
if (Selectoutfile(pf->name)!=0) { // Cancelled by user
|
||||
if (bufout!=NULL) free(bufout); |
||||
return -1; }; |
||||
*/ |
||||
|
||||
//!!! Need means of checking that output file name is valid
|
||||
|
||||
#ifdef _WIN32 |
||||
// Open file and save data.
|
||||
hfile=CreateFile(outfile,GENERIC_WRITE,0,NULL, |
||||
CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); |
||||
if (hfile==INVALID_HANDLE_VALUE) { |
||||
if (bufout!=NULL) GlobalFree((HGLOBAL)bufout); |
||||
Reporterror("Unable to create file"); |
||||
return -1; }; |
||||
WriteFile(hfile,data,length,&l,NULL); |
||||
// Restore old modification date and time.
|
||||
SetFileTime(hfile,&pf->modified,&pf->modified,&pf->modified); |
||||
// Close file and restore old basic attributes.
|
||||
CloseHandle(hfile); |
||||
|
||||
#elif __linux |
||||
// Open file and save data.
|
||||
FILE * pFile; |
||||
pFile = fopen(hfile.c_str(), "wb"); |
||||
|
||||
if( pFile == NULL ) { |
||||
if (bufout!=NULL) { |
||||
free(bufout); |
||||
} |
||||
Reporterror("Unable to create file"); |
||||
return -1; |
||||
} |
||||
|
||||
int dataSize = 1; |
||||
l = fwrite(data, dataSize, length, pFile); |
||||
|
||||
// Restore old modification date and time.
|
||||
struct stat fileAttributes; |
||||
if( stat(hfile.c_str(), &fileAttributes) != 0 ) { |
||||
Reporterror("Stat failed on restored data file"); |
||||
return -1; |
||||
} |
||||
pf->modified = fileAttributes.st_mtime; |
||||
|
||||
// Close file and restore old basic attributes.
|
||||
fclose(pFile); |
||||
#endif |
||||
|
||||
//!!! is it necessary to save file attributes?
|
||||
//SetFileAttributes(outfile,pf->attributes);
|
||||
|
||||
if (bufout!=NULL) free(bufout); |
||||
if (l!=length) { |
||||
Reporterror("I/O error"); |
||||
return -1; }; |
||||
// Close file descriptor and report success.
|
||||
Closefproc(); |
||||
Message("File saved",0); |
||||
return 0; |
||||
}; |
||||
|
||||
|
@ -1,75 +0,0 @@
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
* ===================================================================================== |
||||
* |
||||
* Filename: Fileproc.h |
||||
* |
||||
* Description: |
||||
* |
||||
* Version: 1.2 |
||||
* Created: 07/26/2017 05:32:51 AM |
||||
* Revision: none |
||||
* Compiler: gcc |
||||
* |
||||
* Author: Oleh Yuschuk |
||||
* Modified By: suhrke@teknik.io |
||||
* |
||||
* ===================================================================================== |
||||
*/ |
||||
|
||||
#ifndef FILEPROC_H |
||||
#define FILEPROC_H |
||||
|
||||
#include <string> |
||||
#include "Global.h" |
||||
#ifdef _WIN32 |
||||
#include <windows.h> |
||||
#endif |
||||
|
||||
|
||||
|
||||
|
||||
typedef struct t_fproc { // Descriptor of processed file
|
||||
int busy; // In work
|
||||
// General file data.
|
||||
char name[64]; // File name - may have all 64 chars
|
||||
#ifdef _WIN32 |
||||
FILETIME modified; // Time of last file modification
|
||||
#elif __linux__ |
||||
time_t modified; // Time of last file modification
|
||||
#endif |
||||
ulong attributes; // Basic file attrributes
|
||||
ulong datasize; // Size of (compressed) data
|
||||
ulong pagesize; // Size of (compressed) data on page
|
||||
ulong origsize; // Size of original (uncompressed) data
|
||||
ulong mode; // Special mode bits, set of PBM_xxx
|
||||
int npages; // Total number of pages
|
||||
ulong filecrc; // 16-bit CRC of decrypted packed file
|
||||
// Properties of currently processed page.
|
||||
int page; // Currently processed page
|
||||
int ngroup; // Actual NGROUP on the page
|
||||
ulong minpageaddr; // Minimal address of block on page
|
||||
ulong maxpageaddr; // Maximal address of block on page
|
||||
// Gathered data.
|
||||
int nblock; // Total number of data blocks
|
||||
int ndata; // Number of decoded blocks so far
|
||||
uchar *datavalid; // 0:data invalid, 1:valid, 2:recovery
|
||||
uchar *data; // Gathered data
|
||||
// Statistics.
|
||||
int goodblocks; // Total number of good blocks read
|
||||
int badblocks; // Total number of unreadable blocks
|
||||
ulong restoredbytes; // Total number of bytes restored by ECC
|
||||
int recoveredblocks; // Total number of recovered blocks
|
||||
int rempages[8]; // 1-based list of remaining pages
|
||||
} t_fproc; |
||||
|
||||
//unique
|
||||
extern t_fproc fproc; // Processed file
|
||||
|
||||
void Closefproc(); |
||||
int Startnextpage(t_superblock *superblock); |
||||
int Addblock(t_block *block); |
||||
int Finishpage(int ngood,int nbad,ulong nrestored); |
||||
int Saverestoredfile(int force); |
||||
|
||||
#endif //FILEPROC_H
|
||||
|
@ -1,354 +0,0 @@
@@ -1,354 +0,0 @@
|
||||
/*
|
||||
* ===================================================================================== |
||||
* |
||||
* Filename: Global.h |
||||
* |
||||
* Description: As paperback was designed around global memory management, some |
||||
* must remain global until serious refactoring |
||||
* |
||||
* Version: 1.2 |
||||
* Created: 07/25/2017 09:23:02 AM |
||||
* Revision: none |
||||
* Compiler: gcc |
||||
* |
||||
* Author: Oleh Yuschuk |
||||
* Modified By: suhrke@teknik.io |
||||
* |
||||
* ===================================================================================== |
||||
*/ |
||||
|
||||
#ifndef GLOBAL_H |
||||
#define GLOBAL_H |
||||
|
||||
#include <ctime> |
||||
#include <iostream> |
||||
#include <string> |
||||
#ifdef __WIN32 |
||||
#include <windows.h> |
||||
#endif |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////// GENERAL DEFINITIONS //////////////////////////////
|
||||
|
||||
typedef unsigned char uchar; |
||||
typedef unsigned short ushort; |
||||
typedef unsigned int uint; |
||||
typedef unsigned long ulong; |
||||
|
||||
#define TEXTLEN 256 // Maximal length of strings
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////// DATA PROPERTIES ////////////////////////////////
|
||||
|
||||
// Don't change the definitions below! Program may crash if any modified!
|
||||
#define NDOT 32 // Block X and Y size, dots
|
||||
#define NDATA 90 // Number of data bytes in a block
|
||||
#define MAXSIZE 0x0FFFFF80 // Maximal (theoretical) length of file
|
||||
#define SUPERBLOCK 0xFFFFFFFF // Address of superblock
|
||||
|
||||
#define NGROUP 5 // For NGROUP blocks (1..15), 1 recovery
|
||||
#define NGROUPMIN 2 |
||||
#define NGROUPMAX 10 |
||||
|
||||
//Values set by Borland compiler
|
||||
#define MAXPATH 80 |
||||
#define MAXFILE 9 |
||||
#define MAXEXT 5 |
||||
#define MAXDIR 66 |
||||
#define MAXDRIVE 3 |
||||
|
||||
// Size required by Reed-Solomon ECC
|
||||
#define ECC_SIZE 32 |
||||
|
||||
// Oleh's magic numbers
|
||||
#define FILENAME_SIZE 64 |
||||
|
||||
|
||||
typedef struct __attribute__ ((packed)) t_data { // Block on paper
|
||||