Skip to content

Instantly share code, notes, and snippets.

@kainjow
Created September 24, 2014 01:59
Show Gist options
  • Save kainjow/cb2d3f60c6214e0899ce to your computer and use it in GitHub Desktop.
Save kainjow/cb2d3f60c6214e0899ce to your computer and use it in GitHub Desktop.
Strip EXIF metadata from a JPEG
//
// Created by Kevin Wojniak on 2014/9/23.
// Copyright (c) 2014 Kevin Wojniak. All rights reserved.
//
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
const char *inputFile = argv[1];
const char *outputFile = argv[2];
FILE *inFile = fopen(inputFile, "rb");
if (!inFile) {
NSLog(@"Can't open %s", inputFile);
return 0;
}
FILE *outFile = fopen(outputFile, "w");
if (!outFile) {
(void)fclose(inFile);
NSLog(@"Can't open %@", outFile);
return 0;
}
NSMutableData *data = [NSMutableData data];
unsigned num_markers = 0;
bool gotEndOfImage = false;
for (;;) {
size_t bytes_read;
uint16_t raw_marker;
bytes_read = fread(&raw_marker, 1, sizeof(raw_marker), inFile);
if (bytes_read == 0) {
// done
break;
}
if (bytes_read != sizeof(raw_marker)) {
NSLog(@"Can't read marker: %u", (unsigned)bytes_read);
break;
}
uint16_t marker = NSSwapBigShortToHost(raw_marker);
++num_markers;
if (num_markers == 1 && marker != 0xFFD8) {
NSLog(@"Invalid starting marker %04X", marker);
break;
}
if ((marker >> 8) != 0xFF) {
NSLog(@"Invalid marker %04X", marker);
break;
}
uint64_t len = 0;
bool marker_has_length = true;
if (marker == 0xFFD8 /* Start of Image */) {
if (num_markers != 1) {
NSLog(@"Got Start of Image marker at invalid location.");
break;
}
marker_has_length = false;
} else if (marker == 0xFFD9 /* End of Image */) {
gotEndOfImage = true;
marker_has_length = false;
} else if (marker == 0xFFDA /* Start of Scan */) {
int chr;
while ((chr = fgetc(inFile)) != EOF) {
++len;
if (chr == 0xFF) {
int nextchr = fgetc(inFile);
if (nextchr == 0 || (((nextchr & 0xFF) >= 0xD0) && ((nextchr & 0xFF) <= 0xD7))) {
ungetc(nextchr, inFile);
continue;
}
++len;
if (fseek(inFile, -(long)len, SEEK_CUR) != 0) {
NSLog(@"Can't seek");
}
marker_has_length = false;
len -= sizeof(marker);
break;
}
}
}
NSLog(@"%04X", marker);
uint16_t raw_len = 0;
if (marker_has_length) {
if (fread(&raw_len, 1, sizeof(raw_len), inFile) != sizeof(raw_len)) {
NSLog(@"Can't read marker length.");
break;
}
len = NSSwapBigShortToHost(raw_len);
NSLog(@" = %llu", len);
len -= sizeof(raw_len);
} else {
NSLog(@" ? %llu", len);
}
if (len > 0) {
data.length = len;
if (fread(data.mutableBytes, 1, len, inFile) != len) {
NSLog(@"Can't read %04X's data of length %llu", marker, len);
break;
}
}
if (((marker & 0xFF) >= 0xE0) && ((marker & 0xFF) <= 0xEE)) {
NSLog(@" Skipping");
continue;
}
if (fwrite(&raw_marker, 1, sizeof(raw_marker), outFile) != sizeof(raw_marker)) {
NSLog(@"Can't write marker");
break;
}
if (marker_has_length) {
if (fwrite(&raw_len, 1, sizeof(raw_len), outFile) != sizeof(raw_len)) {
NSLog(@"Can't write length");
break;
}
}
if (len > 0 && fwrite(data.bytes, 1, data.length, outFile) != data.length) {
NSLog(@"Can't write data");
break;
}
}
(void)fclose(outFile);
(void)fclose(inFile);
if (!gotEndOfImage) {
NSLog(@"Didn't get end of image marker");
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment