DICOM dicomdir - eiichiromomma/CVMLAB GitHub Wiki

(DICOM) dicomdir

DICOM画像のスライス順等が入ったファイルを読む

仕様

上の階層の関連リンク参照。 タグごとにサイズが変わりかなり面倒。

サンプルソース

遥か昔にスライス順にファイル名を取得するために作成。ひたすら力技。

#define DEBUG

とするとタグを全て出力する。 タグの網羅は諦めた。

使い方は

DicomdirRead dicomdirファイル

とするだけ。

初めにスライス数を数えて入れ物を用意してと、無駄なことをしているが特に需要も無いので直す予定は無し。 バックアップ代わりに掲載。

    //DicomdirRead.cpp Eiichiro Momma 遥か昔に作成
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    FILE *fp;

    typedef struct _ImageProperty
    {
      int height;
      int width;
      long min;
      long max;
    }iproperty;

    iproperty ip;


    typedef struct _Tag{
      unsigned short   group;
      unsigned short   element;
    }tag;
    typedef enum
    {
      unknown=0,
      StudyDate,
      ImageTime,
      Manufacturer,
      InstitutionName,
      PatientsName,
      PatientsSize,
      PatientsWeight,
      SliceThickness,
      Gantry,
      SliceLocation,
      Rows,
      Columns,
      PixelSpacing,
      PixelAspectRatio,
      BitsAllocated,
      BitsStored,
      HighBit,
      PixelRepresentation,
      SmallestImagePixelValue,
      LargestImagePixelValue,
      WindowCenter,
      WindowWidth,
      PixelData,
      GroupLength,
      FilesetID,
      FilesetDescriptorFileID,
      SpecificCharacterSetOfFilesetDescriptorFile,
      OffsetOfTheFirstDirectoryRecordOfTheRootDirectoryEntity,
      OffsetOfTheLastDirectoryRecordOfTheRootDirectoryEntity,
      FilesetConsistencyFlag,
      DirectoryRecordSequence,
      OffsetOfTheNextDirectoryRecord,
      RecordInuseFlag,
      OffsetOfReferencedLowerLevelDirectoryEntry,
      DirectoryRecordType,
      PrivateRecordUID,
      ReferencedFileID,
      MRDRDirectoryRecordOffset,
      ReferencedSOPClassUIDInFile,
      ReferencedSOPInstanceUIDInFile,
      ReferencedTransferSyntaxUIDInFile,
      NumberOfReferences
    }datatype;

    typedef enum
    {
      i16=0,
      i32,
      other
    }datasize;

    static int fileNo;
    char **fileList;

    int
    myfputs(const char *str, FILE *stream)
    {
    #ifdef DEBUG
      return fputs(str,stream);
    #endif
      ;
    }

    int
    readSQ(char** fl)
    {
      int Count;
      tag t;
      datatype dt;
      datasize sz;
      short size16;
      short data16;
      long data32;
      long size32;
      size_t size;
      char VR[3];
      char *Value;
      VR[0]=VR[1]=VR[2]=0;
      FILE *fpcp;
      if (fl == 0){
        Count=1;
      }else{
        Count=0;
      }
      if (0 == fread(&t,sizeof(_Tag),1,fp)){
        return 1;
      }
      fpcp = fp;
    #ifdef DEBUG
      fprintf(stderr,"%X,%X,",t.group,t.element);
    #endif
      switch (t.group){
      case 0xFFFE:
        switch(t.element){
        case 0xE000:
          myfputs("---------------start--------------\n", stderr);
          fseek(fp,4,SEEK_CUR);
          return 0;
          break;
        case 0xE00D:
          myfputs("-----------------end--------------\n",stderr);
          return 0;
        }
        break;
      case 0x0004:
        switch(t.element){
        case 0x0000:
          dt=GroupLength;
          myfputs("GroupLength,",stderr);
          break;
        case 0x1130:
          dt=FilesetID;
          myfputs("FilesetID,",stderr);
          break;
        case 0x1141:
          dt=FilesetDescriptorFileID;
          myfputs("FilesetDescriptorFileID,",stderr);
          break;
        case 0x1142:
          dt=SpecificCharacterSetOfFilesetDescriptorFile;
          myfputs("SpecificCharacterSetOfFilesetDescriptorFile,",stderr);
          break;
        case 0x1200:
          dt=OffsetOfTheFirstDirectoryRecordOfTheRootDirectoryEntity;
          myfputs("OffsetOfTheFirstDirectoryRecordOfTheRootDirectoryEntity,",stderr);
          break;
        case 0x1202:
          dt=OffsetOfTheLastDirectoryRecordOfTheRootDirectoryEntity;
          myfputs("OffsetOfTheLastDirectoryRecordOfTheRootDirectoryEntity,",stderr);
          break;
        case 0x1212:
          dt=FilesetConsistencyFlag;
          myfputs("FilesetConsistencyFlag,",stderr);
          break;
        case 0x1220:
          dt=DirectoryRecordSequence;
          myfputs("DirectoryRecordSequence,",stderr);
          break;
        case 0x1400:
          dt=OffsetOfTheNextDirectoryRecord;
          myfputs("OffsetOfTheNextDirectoryRecord,",stderr);
          break;
        case 0x1410:
          dt=RecordInuseFlag;
          myfputs("RecordInuseFlag,",stderr);
          break;
        case 0x1420:
          dt=OffsetOfReferencedLowerLevelDirectoryEntry;
          myfputs("OffsetOfReferencedLowerLevelDirectoryEntry,",stderr);
          break;
        case 0x1430:
          dt=DirectoryRecordType;
          myfputs("DirectoryRecordType,",stderr);
          break;
        case 0x1432:
          dt=PrivateRecordUID;
          myfputs("PrivateRecordUID,",stderr);
          break;
        case 0x1500:
          dt=ReferencedFileID;
          myfputs("ReferencedFileID,",stderr);
          break;
        case 0x1504:
          dt=MRDRDirectoryRecordOffset;
          myfputs("MRDRDirectoryRecordOffset,",stderr);
          break;
        case 0x1510:
          dt=ReferencedSOPClassUIDInFile;
          myfputs("ReferencedSOPClassUIDInFile,",stderr);
          break;
        case 0x1511:
          dt=ReferencedSOPInstanceUIDInFile;
          myfputs("ReferencedSOPInstanceUIDInFile,",stderr);
          break;
        case 0x1512:
          dt=ReferencedTransferSyntaxUIDInFile;
          myfputs("ReferencedTransferSyntaxUIDInFile,",stderr);
          break;
        case 0x1600:
          dt=NumberOfReferences;
          myfputs("NumberOfReferences,",stderr);
          break;
        default:
          dt=unknown;
          myfputs("Unknown element,",stderr);
          break;
        }
        break;
      case 0x0008:
        switch(t.element){
        case 0x0020:
          dt=StudyDate;
          myfputs("Study Date,",stderr);
          break;
        case 0x0033:
          dt=ImageTime;
          myfputs("Image Time,",stderr);
          break;
        case 0x0070:
          dt=Manufacturer;
          myfputs("Manufacturer,",stderr);
          break;
        case 0x0080:
          dt=InstitutionName;
          myfputs("Institution Name,",stderr);
          break;
        default:
          dt=unknown;
          myfputs("Unknown element,",stderr);
          break;
        }
        break;
      case 0x0010:
        switch(t.element){
        case 0x0010:
          dt=PatientsName;
          myfputs("Patient's Name,",stderr);
          break;
        case 0x1020:
          dt=PatientsSize;
          myfputs("Patient's Size,",stderr);
          break;
        case 0x1030:
          dt=PatientsWeight;
          myfputs("Patient's Weight,",stderr);
          break;
        default:
          dt=unknown;
          myfputs("Unknown element,",stderr);
          break;
        }
        break;
      case 0x0018:
        switch(t.element){
        case 0x0050:
          dt=SliceThickness;
          myfputs("Slice Thickness,",stderr);
          break;
        case 0x1120:
          dt=Gantry;
          myfputs("Gantry,",stderr);
          break;
        default:
          dt=unknown;
          myfputs("Unknown element,",stderr);
          break;
        }
        break;
      case 0x0028:
        switch(t.element){
        case 0x0010:
          dt=Rows;
          myfputs("Rows,",stderr);
          break;
        case 0x0011:
          dt=Columns;
          myfputs("Columns,",stderr);
          break;
        case 0x0030:
          dt=PixelSpacing;
          myfputs("Pixel Spacing,",stderr);
          break;
        case 0x0034:
          dt=PixelAspectRatio;
          myfputs("PixelAspectRatio,",stderr);
          break;
        case 0x0100:
          dt=BitsAllocated;
          myfputs("Bits Allocated,",stderr);
          break;
        case 0x0101:
          dt=BitsStored;
          myfputs("BitsStored,",stderr);
          break;
        case 0x0102:
          dt=HighBit;
          myfputs("High Bit,",stderr);
          break;
        case 0x0103:
          dt=PixelRepresentation;
          myfputs("Pixel Representation,",stderr);
          break;
        case 0x0106:
          dt=SmallestImagePixelValue;
          myfputs("Smallest Image Pixel Value,",stderr);
          break;
        case 0x0107:
          dt=LargestImagePixelValue;
          myfputs("Largest Image Pixel Value,",stderr);
          break;
        case 0x1050:
          dt=WindowCenter;
          myfputs("Window Center,",stderr);
          break;
        case 0x1051:
          dt=WindowWidth;
          myfputs("Window Width,",stderr);
          break;
        default:
          dt=unknown;
          myfputs("Unknown element,",stderr);
          break;
        }
        break;
      case 0x7FE0:
        switch(t.element){
        case 0x0010:
          dt=PixelData;
          myfputs("PixelData,",stderr);
          break;
        }
        break;
      default:
        dt=unknown;
        myfputs("Unknown Tag,",stderr);
        break;
      }
      fread(VR,2,1,fp);
      switch((int)VR[0]){
      case 'A':
        switch((int)VR[1]){
        case 'E':
        case 'S':
        case 'T':
          myfputs(VR,stderr);
          myfputs(",",stderr);
          sz=i16;
          break;
        }
        break;
      case 'C':
        if (VR[1] == 'S'){
          myfputs(VR,stderr);
          myfputs(",",stderr);
          sz=i16;
        }
        break;
      case 'D':
        switch((int)VR[1]){
        case 'A':
        case 'S':
        case 'T':
          myfputs(VR,stderr);
          myfputs(",",stderr);
          sz=i16;
          break;
        }
        break;
      case 'F':
        switch((int)VR[1]){
        case 'L':
        case 'D':
          myfputs(VR,stderr);
          myfputs(",",stderr);
          sz=i16;
          break;
        }
        break;
      case 'I':
        if ((int)VR[1] == 'S'){
          myfputs(VR,stderr);
          myfputs(",",stderr);
          sz=i16;
        }
        break;
      case 'L':
        switch((int)VR[1]){
        case 'O':
        case 'T':
          myfputs(VR,stderr);
          myfputs(",",stderr);
          sz=i16;
          break;
        }
        break;
      case 'O':
        switch((int)VR[1]){
        case 'B':
        case 'W':
          myfputs(VR,stderr);
          myfputs(",",stderr);
          sz=i32;
          fseek(fp,2,SEEK_CUR);
          break;
        }
        break;
      case 'P':
        if ((int)VR[1] == 'N'){
          myfputs(VR,stderr);
          myfputs(",",stderr);
          sz=i16;
        }
        break;
      case 'S':
        switch((int)VR[1]){
        case 'Q':
          myfputs(VR,stderr);
          myfputs(",",stderr);
          sz=i32;
          fseek(fp,2,SEEK_CUR);
          break;
        case 'H':
        case 'L':
        case 'S':
        case 'T':
          myfputs(VR,stderr);
          myfputs(",",stderr);
          sz=i16;
          break;
        }
        break;
      case 'T':
        if ((int)VR[1] == 'M'){
          myfputs(VR,stderr);
          myfputs(",",stderr);
          sz=i16;
        }
        break;
      case 'U':
        switch((int)VR[1]){
        case 'N':
          myfputs(VR,stderr);
          myfputs(",",stderr);
          sz=i32;
          fseek(fp,2,SEEK_CUR);
          break;
        case 'I':
        case 'L':
        case 'S':
          myfputs(VR,stderr);
          myfputs(",",stderr);
          sz=i16;
          break;
        }
        break;
      default:
        myfputs("No VR.,",stderr);
        fseek(fp,-2,SEEK_CUR);
        //    fp = fpcp;
        sz=i32;
        break;
      }
      switch(sz){
      case i16:
        fread(&size16,2,1,fp);
        size=size16;
        break;
      case i32:
        fread(&size32,4,1,fp);
        size= size32;
        break;
      }
    #ifdef DEBUG
      fprintf(stderr,"%d,",size);
    #endif
      if (VR[0] == 'U' && VR[1] == 'S'){
        fread(&data16,2,1,fp);
    #ifdef DEBUG
        fprintf(stderr,"%d\n",data16);
    #endif
      }else if(VR[0] == 'U' && VR[1] == 'L'){
        fread(&data32,4,1,fp);
    #ifdef DEBUG
        fprintf(stderr,"%d\n",data32);
    #endif
      }else{
        Value = (char *)malloc(size);
        fread(Value,size,1,fp);
        if (dt==ReferencedFileID){
          if (!Count){
    	strcpy(*(fl+fileNo),Value);
    	//	printf("%d,%s\n",fileNo,*(fl+fileNo));
          }
          fileNo++;
        }else{
          myfputs(Value,stderr);
          myfputs("\n",stderr);
        }
      }
      return 0;
    }  

    int
    readTag(char** fl)
    {
      tag t;
      FILE *fpcp;
      datatype dt;
      datasize sz;
      short size16;
      short data16;
      long data32;
      long size32;
      size_t size;
      char VR[3];
      char *Value;
      VR[0]=VR[1]=VR[2]=0;
      if (0 == fread(&t,sizeof(_Tag),1,fp)){
        return 1;
      }
      fpcp=fp;
    #ifdef DEBUG
      fprintf(stderr,"%X,%X,",t.group,t.element);
    #endif
      switch (t.group){
      case 0x0004:
        switch(t.element){
        case 0x0000:
          dt=GroupLength;
          myfputs("GroupLength,",stderr);
          break;
        case 0x1130:
          dt=FilesetID;
          myfputs("FilesetID,",stderr);
          break;
        case 0x1141:
          dt=FilesetDescriptorFileID;
          myfputs("FilesetDescriptorFileID,",stderr);
          break;
        case 0x1142:
          dt=SpecificCharacterSetOfFilesetDescriptorFile;
          myfputs("SpecificCharacterSetOfFilesetDescriptorFile,",stderr);
          break;
        case 0x1200:
          dt=OffsetOfTheFirstDirectoryRecordOfTheRootDirectoryEntity;
          myfputs("OffsetOfTheFirstDirectoryRecordOfTheRootDirectoryEntity,",stderr);
          break;
        case 0x1202:
          dt=OffsetOfTheLastDirectoryRecordOfTheRootDirectoryEntity;
          myfputs("OffsetOfTheLastDirectoryRecordOfTheRootDirectoryEntity,",stderr);
          break;
        case 0x1212:
          dt=FilesetConsistencyFlag;
          myfputs("FilesetConsistencyFlag,",stderr);
          break;
        case 0x1220:
          dt=DirectoryRecordSequence;
          myfputs("DirectoryRecordSequence,",stderr);
          break;
        case 0x1400:
          dt=OffsetOfTheNextDirectoryRecord;
          myfputs("OffsetOfTheNextDirectoryRecord,",stderr);
          break;
        case 0x1410:
          dt=RecordInuseFlag;
          myfputs("RecordInuseFlag,",stderr);
          break;
        case 0x1420:
          dt=OffsetOfReferencedLowerLevelDirectoryEntry;
          myfputs("OffsetOfReferencedLowerLevelDirectoryEntry,",stderr);
          break;
        case 0x1430:
          dt=DirectoryRecordType;
          myfputs("DirectoryRecordType,",stderr);
          break;
        case 0x1432:
          dt=PrivateRecordUID;
          myfputs("PrivateRecordUID,",stderr);
          break;
        case 0x1500:
          dt=ReferencedFileID;
          myfputs("ReferencedFileID,",stderr);
          break;
        case 0x1504:
          dt=MRDRDirectoryRecordOffset;
          myfputs("MRDRDirectoryRecordOffset,",stderr);
          break;
        case 0x1510:
          dt=ReferencedSOPClassUIDInFile;
          myfputs("ReferencedSOPClassUIDInFile,",stderr);
          break;
        case 0x1511:
          dt=ReferencedSOPInstanceUIDInFile;
          myfputs("ReferencedSOPInstanceUIDInFile,",stderr);
          break;
        case 0x1512:
          dt=ReferencedTransferSyntaxUIDInFile;
          myfputs("ReferencedTransferSyntaxUIDInFile,",stderr);
          break;
        case 0x1600:
          dt=NumberOfReferences;
          myfputs("NumberOfReferences,",stderr);
          break;
        default:
          dt=unknown;
          myfputs("Unknown element,",stderr);
          break;
        }
        break;
      case 0x0008:
        switch(t.element){
        case 0x0020:
          dt=StudyDate;
          myfputs("Study Date,",stderr);
          break;
        case 0x0033:
          dt=ImageTime;
          myfputs("Image Time,",stderr);
          break;
        case 0x0070:
          dt=Manufacturer;
          myfputs("Manufacturer,",stderr);
          break;
        case 0x0080:
          dt=InstitutionName;
          myfputs("Institution Name,",stderr);
          break;
        default:
          dt=unknown;
          myfputs("Unknown element,",stderr);
          break;
        }
        break;
      case 0x0010:
        switch(t.element){
        case 0x0010:
          dt=PatientsName;
          myfputs("Patient's Name,",stderr);
          break;
        case 0x1020:
          dt=PatientsSize;
          myfputs("Patient's Size,",stderr);
          break;
        case 0x1030:
          dt=PatientsWeight;
          myfputs("Patient's Weight,",stderr);
          break;
        default:
          dt=unknown;
          myfputs("Unknown element,",stderr);
          break;
        }
        break;
      case 0x0018:
        switch(t.element){
        case 0x0050:
          dt=SliceThickness;
          myfputs("Slice Thickness,",stderr);
          break;
        case 0x1120:
          dt=Gantry;
          myfputs("Gantry,",stderr);
          break;
        default:
          dt=unknown;
          myfputs("Unknown element,",stderr);
          break;
        }
        break;
      case 0x0028:
        switch(t.element){
        case 0x0010:
          dt=Rows;
          myfputs("Rows,",stderr);
          break;
        case 0x0011:
          dt=Columns;
          myfputs("Columns,",stderr);
          break;
        case 0x0030:
          dt=PixelSpacing;
          myfputs("Pixel Spacing,",stderr);
          break;
        case 0x0034:
          dt=PixelAspectRatio;
          myfputs("PixelAspectRatio,",stderr);
          break;
        case 0x0100:
          dt=BitsAllocated;
          myfputs("Bits Allocated,",stderr);
          break;
        case 0x0101:
          dt=BitsStored;
          myfputs("BitsStored,",stderr);
          break;
        case 0x0102:
          dt=HighBit;
          myfputs("High Bit,",stderr);
          break;
        case 0x0103:
          dt=PixelRepresentation;
          myfputs("Pixel Representation,",stderr);
          break;
        case 0x0106:
          dt=SmallestImagePixelValue;
          myfputs("Smallest Image Pixel Value,",stderr);
          break;
        case 0x0107:
          dt=LargestImagePixelValue;
          myfputs("Largest Image Pixel Value,",stderr);
          break;
        case 0x1050:
          dt=WindowCenter;
          myfputs("Window Center,",stderr);
          break;
        case 0x1051:
          dt=WindowWidth;
          myfputs("Window Width,",stderr);
          break;
        default:
          dt=unknown;
          myfputs("Unknown element,",stderr);
          break;
        }
        break;
      case 0x7FE0:
        switch(t.element){
        case 0x0010:
          dt=PixelData;
          myfputs("PixelData,",stderr);
          break;
        }
        break;
      default:
        dt=unknown;
        myfputs("Unknown Tag,",stderr);
        break;
      }
      fread(VR,2,1,fp);
      switch((int)VR[0]){
      case 'A':
        switch((int)VR[1]){
        case 'E':
        case 'S':
        case 'T':
          myfputs(VR,stderr);
          myfputs(",",stderr);
          sz=i16;
          break;
        }
        break;
      case 'C':
        if (VR[1] == 'S'){
          myfputs(VR,stderr);
          myfputs(",",stderr);
          sz=i16;
        }
        break;
      case 'D':
        switch((int)VR[1]){
        case 'A':
        case 'S':
        case 'T':
          myfputs(VR,stderr);
          myfputs(",",stderr);
          sz=i16;
          break;
        }
        break;
      case 'F':
        switch((int)VR[1]){
        case 'L':
        case 'D':
          myfputs(VR,stderr);
          myfputs(",",stderr);
          sz=i16;
          break;
        }
        break;
      case 'I':
        if ((int)VR[1] == 'S'){
          myfputs(VR,stderr);
          myfputs(",",stderr);
          sz=i16;
        }
        break;
      case 'L':
        switch((int)VR[1]){
        case 'O':
        case 'T':
          myfputs(VR,stderr);
          myfputs(",",stderr);
          sz=i16;
          break;
        }
        break;
      case 'O':
        switch((int)VR[1]){
        case 'B':
        case 'W':
          myfputs(VR,stderr);
          myfputs(",",stderr);
          sz=i32;
          fseek(fp,2,SEEK_CUR);
          break;
        }
        break;
      case 'P':
        if ((int)VR[1] == 'N'){
          myfputs(VR,stderr);
          myfputs(",",stderr);
          sz=i16;
        }
        break;
      case 'S':
        switch((int)VR[1]){
        case 'Q':
          myfputs(VR,stderr);
          myfputs(",",stderr);
          sz=i32;
          fseek(fp,2,SEEK_CUR);
          break;
        case 'H':
        case 'L':
        case 'S':
        case 'T':
          myfputs(VR,stderr);
          myfputs(",",stderr);
          sz=i16;
          break;
        }
        break;
      case 'T':
        if ((int)VR[1] == 'M'){
          myfputs(VR,stderr);
          myfputs(",",stderr);
          sz=i16;
        }
        break;
      case 'U':
        switch((int)VR[1]){
        case 'N':
          myfputs(VR,stderr);
          myfputs(",",stderr);
          sz=i32;
          fseek(fp,2,SEEK_CUR);
          break;
        case 'I':
        case 'L':
        case 'S':
          myfputs(VR,stderr);
          myfputs(",",stderr);
          sz=i16;
          break;
        }
        break;
      default:
        myfputs("No VR.,",stderr);
        fseek(fp,-2,SEEK_CUR);
        //    fp = fpcp;
        sz=i32;
        break;
      }
      switch(sz){
      case i16:
        fread(&size16,2,1,fp);
        size=size16;
        break;
      case i32:
        fread(&size32,4,1,fp);
        size= size32;
        if (dt == DirectoryRecordSequence){
          myfputs("\n",stderr);
          while(0==readSQ(fl));
          return 0;
        }
        break;
      }
    #ifdef DEBUG
      fprintf(stderr,"%d,",size);
    #endif
      if (VR[0] == 'U' && VR[1] == 'S'){
        fread(&data16,2,1,fp);
    #ifdef DEBUG
        fprintf(stderr,"%d\n",data16);
    #endif
      }else if(VR[0] == 'U' && VR[1] == 'L'){
        fread(&data32,4,1,fp);
    #ifdef DEBUG
        fprintf(stderr,"%d\n",data32);
    #endif
      }else{
        Value = (char *)malloc(size);
        fread(Value,size,1,fp);
        myfputs(Value,stderr);
        myfputs("\n",stderr);
      }

      switch(dt){
      case Rows:
        ip.width = data16;
        break;
      case Columns:
        ip.height = data16;
        break;
      case SmallestImagePixelValue:
        ip.min = data16;
        break;
      case LargestImagePixelValue:
        ip.max = data16;
        break;
      default:
        break;
      }

      return 0;
    }

    int
    main (int argc, char **argv)
    {
      unsigned char c;
      int i;
      long place;
      fileNo=0;
      if ((fp=fopen(argv[1],"rb")) == NULL){
        myfputs("Can't open file\n",stderr);    
        return 1;
      }
      while ((c=fgetc(fp)) == 0x0);
      if ( c != 'D' ||
           (c=fgetc(fp)) != 'I' ||
           (c=fgetc(fp)) != 'C' ||
           (c=fgetc(fp)) != 'M'){
        myfputs("Not DICOM File\n",stderr);
        return 1;
      }
      myfputs("DICOM File\n",stderr);
      place = ftell(fp);

      while(0 == readTag(0));
      fileList = (char **)malloc((fileNo+1)*sizeof(char*));
      for (i=0; i<fileNo; i++){
        *(fileList+i) = (char *)malloc(256*sizeof(char));
        **(fileList+i)=0;
      }
      fileNo=0;

      fseek(fp,place,SEEK_SET);
      while(0 == readTag(fileList));

      for (i=0; i<fileNo; i++){
        fputs(*(fileList+i),stderr);
        fputs("\n",stderr);
      }
      return 0;
    }
⚠️ **GitHub.com Fallback** ⚠️