This will attempt to parse makernotes and return it as an IFD */
| 128 | |
| 129 | /* This will attempt to parse makernotes and return it as an IFD */ |
| 130 | TiffRootIFDOwner TiffIFD::parseMakerNote(NORangesSet<Buffer>* ifds, |
| 131 | TiffEntry* t) { |
| 132 | assert(ifds); |
| 133 | |
| 134 | // go up the IFD tree and try to find the MAKE entry on each level. |
| 135 | // we can not go all the way to the top first because this partial tree |
| 136 | // is not yet added to the TiffRootIFD. |
| 137 | TiffIFD* p = this; |
| 138 | TiffEntry* makeEntry; |
| 139 | do { |
| 140 | makeEntry = p->getEntryRecursive(MAKE); |
| 141 | p = p->parent; |
| 142 | } while (!makeEntry && p); |
| 143 | string make = makeEntry != nullptr ? trimSpaces(makeEntry->getString()) : ""; |
| 144 | |
| 145 | ByteStream bs = t->getData(); |
| 146 | |
| 147 | // helper function for easy setup of ByteStream buffer for the different maker note types |
| 148 | // 'rebase' means position 0 of new stream equals current position |
| 149 | // 'newPosition' is the position where the IFD starts |
| 150 | // 'byteOrderOffset' is the position where the 2 magic bytes (II/MM) may be found |
| 151 | // 'context' is a string providing error information in case the byte order parsing should fail |
| 152 | auto setup = [&bs](bool rebase, uint32_t newPosition, |
| 153 | uint32_t byteOrderOffset = 0, |
| 154 | const char* context = nullptr) { |
| 155 | if (rebase) |
| 156 | bs = bs.getSubStream(bs.getPosition(), bs.getRemainSize()); |
| 157 | if (context) |
| 158 | bs.setByteOrder(getTiffByteOrder(bs, byteOrderOffset, context)); |
| 159 | bs.skipBytes(newPosition); |
| 160 | }; |
| 161 | |
| 162 | if (bs.hasPrefix("AOC\0", 4)) { |
| 163 | setup(false, 6, 4, "Pentax makernote"); |
| 164 | } else if (bs.hasPrefix("PENTAX", 6)) { |
| 165 | setup(true, 10, 8, "Pentax makernote"); |
| 166 | } else if (bs.hasPrefix("FUJIFILM\x0c\x00\x00\x00", 12)) { |
| 167 | bs.setByteOrder(Endianness::little); |
| 168 | setup(true, 12); |
| 169 | } else if (bs.hasPrefix("Nikon\x00\x02", 7)) { |
| 170 | // this is Nikon type 3 maker note format |
| 171 | // TODO: implement Nikon type 1 maker note format |
| 172 | // see http://www.ozhiker.com/electronics/pjmt/jpeg_info/nikon_mn.html |
| 173 | bs.skipBytes(10); |
| 174 | setup(true, 8, 0, "Nikon makernote"); |
| 175 | } else if (bs.hasPrefix("OLYMPUS", 7)) { // new Olympus |
| 176 | setup(true, 12); |
| 177 | } else if (bs.hasPrefix("OLYMP", 5)) { // old Olympus |
| 178 | setup(true, 8); |
| 179 | } else if (bs.hasPrefix("EPSON", 5)) { |
| 180 | setup(false, 8); |
| 181 | } else if (bs.hasPatternAt("Exif", 4, 6)) { |
| 182 | // TODO: for none of the rawsamples.ch files from Panasonic is this true, instead their MakerNote start with "Panasonic" |
| 183 | // Panasonic has the word Exif at byte 6, a complete Tiff header starts at byte 12 |
| 184 | // This TIFF is 0 offset based |
| 185 | setup(false, 20, 12, "Panosonic makernote"); |
| 186 | } else if (make == "SAMSUNG") { |
| 187 | // Samsung has no identification in its MakerNote but starts with the IFD right away |
nothing calls this directly
no test coverage detected