昔のエントリでXMPってのが何ぞや、というのはわかったんですが、
じゃあその無駄なXMPメタデータをどげんかせんといかん、と。

そういうわけで、GIF画像からXMPデータを削除するプログラムを書いてみました。

//rmxmp.c

#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>

#define TYPE_GIF 1

int fileType(char*);
int removeXmp_GIF(char*);

int main(int argc, char *argv[])
{
  if(0 < argc){
    for(int i=1; i < argc; i++){
      switch(fileType(argv[i])){
      case TYPE_GIF:
        removeXmp_GIF(argv[i]);
        break;
      }
    }
  }
  return 0;
}

int fileType(char* fileName){
  FILE* fp = NULL;
  if((fp = fopen(fileName, "r")) == NULL){
    return -1;
  }

  char data[7] = {0};
  fread(data, 1, 6, fp);
  if(strcmp("GIF89a", data) == 0){
    //GIF
    return TYPE_GIF;
  };

  // other files


  fclose(fp);
  return -1;
}

int removeXmp_GIF(char* fileName){
  char xmp[] = {0x0b, 0x58, 0x4d, 0x50, 0x20, 0x44,
                    0x61, 0x74, 0x61, 0x58, 0x4d, 0x50};
  bool exists = false;
  int c;
  long s, e, f;

  FILE* fp = NULL;
  if((fp = fopen(fileName, "r")) == NULL){
    return -1;
  }

  fseek(fp, 0, SEEK_END);
  f = ftell(fp);
  rewind(fp);

  while((c=fgetc(fp)) != EOF){
    if(c == 0x21 && fgetc(fp) == 0xff){
      // application extension
      char data[12] = {0};
      fread(data, 1, 12, fp);
      if(memcmp(data, xmp, 12) == 0){
        s = ftell(fp) - 14;
        exists = true;
        break;
      }
    }
  }
  if(!exists){
    return 1;
  }

  // XMPデータサイズの計測
  while((c=fgetc(fp)) != EOF){
    if(c != 0x00){
      fseek(fp, c, SEEK_CUR);
    }
    else{
      e = ftell(fp);
      break;
    }
  }

  char* remain = (char *)malloc((size_t)(f - (e - s)));

  // XMP以外を読み込み
  fseek(fp, 0, SEEK_SET);
  fread(remain, 1, s, fp);

  fseek(fp, e, SEEK_SET);
  fread(remain+s, 1, f-e, fp);

  fclose(fp);

  // 新規作成
  char tmp[ L_tmpnam ];
  tmpnam(tmp);
  if((fp = fopen(tmp, "w+")) == NULL){
    return -1;
  }
  fwrite(remain, 1, (f - (e - s)), fp);

  free(remain);
  fclose(fp);

  // 置き換え
  remove(fileName);
  rename(tmp, fileName);

  return 0;
}

久しぶりのC言語。

マジックナンバー入りまくってますが、クレームは受け付けません。

cygwinからコンパイルして出来た実行ファイルに対象のファイルを引数に渡せば、
XMPが削除されたファイルに置き換えられます。

$ gcc -std=c99 -o rmxmp.exe rmxmp.c
$ ./rmxmp *.gif

試した感じではとりあえず動くっぽいです。

テストはあんまりしてないので利用は自己責任で。
なおGIF以外の画像には対応してません。私には必要なかったので。

気が向いたら対応するかもです。