-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add jpeg_rescue.c and jpeg_truncate.c and Makefile
- Loading branch information
KOMURA Takaaki
committed
Mar 9, 2010
1 parent
abb2cef
commit 439f48a
Showing
4 changed files
with
217 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
ALLTARGETS=jpeg_rescue jpeg_truncate | ||
|
||
all: $(ALLTARGETS) | ||
|
||
jpeg_rescue: jpeg_rescue.o | ||
$(CC) -o $@ $> | ||
|
||
jpeg_truncate: jpeg_truncate.o | ||
$(CC) -o $@ $> | ||
|
||
|
||
clean: | ||
rm *.o $(ALLTARGETS) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
These tools rescue JPEG files from broken SD/USB memory cards | ||
|
||
* jpeg_rescue | ||
|
||
'jpeg_rescue' rescues JPEG files from broken SD/USB memory cards. | ||
This tool expects JPEG files are wrote sequentially in memory device. | ||
|
||
This tool searches JPEG Start Of Image (0xff 0xd8) from top of | ||
each cluster (4KB block) and pick up data (to just before next SOI). | ||
|
||
usage: | ||
|
||
1. insert broekn SD/USB memory into slot of your PC. | ||
2. when your memory device appears in /dev/da0 | ||
# dd if=/dev/da0 of=hogehoge bs=1m | ||
# jpeg_rescue hogehoge | ||
or | ||
# jpeg_rescue /dev/da0 | ||
|
||
|
||
* jpeg_truncate | ||
'jpeg_truncate' truncates unnecessary end of data | ||
This tool trancate garbage after JPEG End Of Image (0xff 0xd9) | ||
|
||
usage: | ||
% jpeg_truncate *.jpg |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
#include <stdio.h> | ||
#include <sys/types.h> | ||
#include <sys/stat.h> | ||
|
||
#define MAXBUF 4096 | ||
#define BLOCKSIZE 4096 | ||
#define MAXJPEGSIZE (1024*1024*10) | ||
|
||
int is_jpeg_startofimage(unsigned char *buf) | ||
{ | ||
if(buf[0] == 0xff && | ||
buf[1] == 0xd8){ | ||
return 1; | ||
} else { | ||
return 0; | ||
} | ||
} | ||
|
||
|
||
int main(int argc, char** argv) | ||
{ | ||
FILE *ifp; | ||
char *ifname; | ||
|
||
FILE *ofp = NULL; | ||
char ofname[8+1+3+1]; | ||
size_t oflen; | ||
|
||
unsigned char buf[MAXBUF]; | ||
int cl = 0; | ||
|
||
int i = 0; | ||
|
||
if(argc != 2){ | ||
fprintf(stderr, "please specify filename\n"); | ||
return -1; | ||
} | ||
ifname = argv[1]; | ||
|
||
if((ifp=fopen(ifname, "r"))==NULL){ | ||
fprintf(stderr, "can not open file: '%s'\n", ifname); | ||
return -1; | ||
} | ||
|
||
while(!feof(ifp)){ | ||
int err; | ||
|
||
cl++; | ||
if((err=fread(buf, BLOCKSIZE, 1, ifp))!=1){ | ||
fprintf(stderr, "fread: error=%d, skip cl=%ld\n", err, cl); | ||
continue; | ||
} | ||
if(oflen > MAXJPEGSIZE){ | ||
fprintf(stderr, ", cut [%ld]\n", oflen); | ||
fclose(ofp); | ||
ofp = NULL; | ||
oflen = 0; | ||
} | ||
if(is_jpeg_startofimage(buf)){ | ||
if(ofp!=NULL){ | ||
fprintf(stderr, ", done [%ld]\n", oflen); | ||
fclose(ofp); | ||
ofp = NULL; | ||
oflen = 0; | ||
} | ||
snprintf(ofname, sizeof(ofname), "%08ld.jpg", i++); | ||
fprintf(stderr, "writing: %s", ofname); | ||
oflen = 0; | ||
if((ofp = fopen(ofname, "w"))==NULL){ | ||
fprintf(stderr, ": faile\n"); | ||
continue; | ||
} | ||
|
||
} | ||
if(ofp == NULL){ | ||
fprintf(stderr, "skip: cl=%d because ofp=NULL\n", cl); | ||
continue; | ||
} | ||
if((err=fwrite(buf, BLOCKSIZE, 1, ofp))!=1){ | ||
fprintf(stderr, "fwrite: error=%d, skip cl=%ld\n", err, cl); | ||
continue; | ||
} | ||
oflen += BLOCKSIZE; | ||
} | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
#include <assert.h> | ||
#include <fcntl.h> | ||
#include <stdio.h> | ||
#include <unistd.h> | ||
#include <sys/mman.h> | ||
#include <sys/types.h> | ||
#include <sys/stat.h> | ||
|
||
#define BUFMAX 4096 | ||
|
||
long where_jpeg_endofimage(unsigned char *buf, long size) | ||
{ | ||
long p; | ||
int stage = 0; | ||
|
||
for(p = size-1; p>0l; p--){ | ||
switch(stage){ | ||
case 0: | ||
if(buf[p] == 0xd9){ | ||
stage++; | ||
} | ||
break; | ||
case 1: | ||
if(buf[p] == 0xff){ | ||
stage++; | ||
} else { | ||
stage--; | ||
} | ||
break; | ||
case 2: | ||
return p + 3; | ||
break; | ||
default: | ||
fprintf(stderr, "unsupported stage: %d\n", stage); | ||
break; | ||
} | ||
} | ||
return 0; | ||
} | ||
|
||
|
||
size_t getfilesize(int fd) | ||
{ | ||
struct stat sb; | ||
|
||
assert(fstat(fd, &sb) >= 0); | ||
return sb.st_size; | ||
} | ||
|
||
|
||
int jpeg_trancate(char *ifname) | ||
{ | ||
int ifd; | ||
void *ifmap; | ||
long ifsize; | ||
long offset; | ||
|
||
ifd = open(ifname, O_RDWR); | ||
assert(ifd != -1); | ||
ifsize = getfilesize(ifd); /* get file size */ | ||
|
||
fprintf(stderr, "open %s [%ld]", ifname, ifsize); | ||
|
||
ifmap = mmap(NULL, ifsize, PROT_READ, MAP_PRIVATE, ifd, 0); | ||
assert(ifmap != MAP_FAILED); | ||
|
||
offset = where_jpeg_endofimage(ifmap, ifsize); | ||
|
||
fprintf(stderr, " -> [%ld = 0x%x] (%ld)\n", offset, offset, offset-ifsize); | ||
|
||
ftruncate(ifd, offset); | ||
fprintf(stderr, "truncated\n"); | ||
return offset; | ||
} | ||
|
||
|
||
int main(int argc, char **argv) | ||
{ | ||
int i; | ||
|
||
if(argc < 2){ | ||
fprintf(stderr, "please specify file name\n"); | ||
return -1; | ||
} | ||
|
||
for(i = 1; i < argc; i++){ | ||
jpeg_trancate(argv[i]); | ||
} | ||
return 0; | ||
} | ||
|