/* file: edf-anonymize.c G. Moody 28 April 2010 ------------------------------------------------------------------------------- edf-anonymize: Make an anonymized copy of an EDF/EDF+ file Copyright (C) 2010 George B. Moody This program 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 2 of the License, or (at your option) any later version. This program 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, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. You may contact the author by e-mail (george@mit.edu) or postal mail (MIT Room E25-505A, Cambridge, MA 02139 USA). For updates to this software, please visit PhysioNet (http://www.physionet.org/). _______________________________________________________________________________ */ #include #include #include main(int argc, char **argv) { static char buf[1024]; FILE *ifile, *ofile; int i, n; if (argc < 3 || strcmp(argv[1], argv[2]) == 0) { fprintf(stderr, "usage: %s INPUT OUTPUT [SNAME [SID [SDM]]]\n" " where INPUT is the name of the EDF file to be anonymized,\n" " OUTPUT is the name of the anonymized EDF file to be written,\n" " SNAME and SID are the surrogate name and ID to be written into OUTPUT,\n" " and SDM is the surrogate day and month to be written, in the form DD.MM\n" " SNAME and SID are optional and empty by default; SDM is optional and is\n" " '01.01' (1 January) by default\n", argv[0]); exit(1); } if ((ifile = fopen(argv[1], "rb")) == NULL) { fprintf(stderr, "%s: can't open %s\n", argv[0], argv[1]); exit(2); } /* All EDF/EDF+ files begin with a 256-byte fixed-format header */ n = fread(buf, 1, sizeof(buf), ifile); if (n < 256) { fprintf(stderr, "%s: %s is too short for an EDF/EDF+ file\n" " No output written\n", argv[0], argv[1]); fclose(ifile); exit(3); } /* Replace name with surrogate name. */ i = 0; if (argc > 3) for (i = 0; i < 80 && argv[3][i]; i++) buf[i+8] = argv[3][i]; for ( ; i < 80; i++) buf[i+8] = ' '; /* Replace id with surrogate id. */ i = 0; if (argc > 4) for (i = 0; i < 80 && argv[4][i]; i++) buf[i+88] = argv[4][i]; for ( ; i < 80; i++) buf[i+88] = ' '; /* Replace date with surrogate date. */ if (argc > 5) { if (strlen(argv[5]) == 5 && argv[5][2] == '.') strncpy(buf+168, argv[5], 5); else { fprintf(stderr, "%s: improper format for surrogate day and month\n" " Correct format is DD.MM (e.g. 05.09 is 5 September)\n", argv[0]); fclose(ifile); exit(4); } } else strncpy(buf+168, "01.01", 5); /* 01.01 is 1 January */ if ((ofile = fopen(argv[2], "wb")) == NULL) { fprintf(stderr, "%s: can't open %s\n", argv[0], argv[2]); fclose(ifile); exit(5); } /* Check the format and warn if the reserved area is not empty. */ if (strncmp("EDF+C", buf+192, 5) == 0) { fprintf(stderr, "Format: EDF+C\n"); i = 5; } else if (strncmp("EDF+D", buf+192, 5) == 0) { fprintf(stderr, "Format: EDF+D\n"); i = 5; } else { fprintf(stderr, "Format: EDF\n"); i = 0; } for ( ; i < 44; i++) { if (buf[i+192] != ' ') { fprintf(stderr, "%s: WARNING\n" " Reserved area of header is not empty as expected\n" " Check for possible PHI in bytes %d-236 of %s\n", argv[0], i+192, argv[2]); break; } } /* Write the output, beginning with the anonymized header and copying the remainder of the input. */ do fwrite(buf, 1, n, ofile); while (n = fread(buf, 1, 1024, ifile)); fclose(ofile); fclose(ifile); exit(0); }