Created
September 24, 2014 01:59
-
-
Save kainjow/cb2d3f60c6214e0899ce to your computer and use it in GitHub Desktop.
Strip EXIF metadata from a JPEG
This file contains hidden or 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
// | |
// 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