| 150 | } |
| 151 | |
| 152 | void MosDecoder::decodeMetaDataInternal(const CameraMetaData* meta) { |
| 153 | RawDecoder::setMetaData(meta, make, model, "", 0); |
| 154 | |
| 155 | // Fetch the white balance (see dcraw.c parse_mos for more metadata that can be gotten) |
| 156 | if (mRootIFD->hasEntryRecursive(LEAFMETADATA)) { |
| 157 | ByteStream bs = mRootIFD->getEntryRecursive(LEAFMETADATA)->getData(); |
| 158 | |
| 159 | // We need at least a couple of bytes: |
| 160 | // "NeutObj_neutrals" + 28 bytes binary + 4x uint as strings + 3x space + \0 |
| 161 | const uint32_t minSize = 16 + 28 + 4 + 3 + 1; |
| 162 | |
| 163 | // dcraw does actual parsing, since we just want one field we bruteforce it |
| 164 | while (bs.getRemainSize() > minSize) { |
| 165 | if (bs.skipPrefix("NeutObj_neutrals", 16)) { |
| 166 | bs.skipBytes(28); |
| 167 | // check for nulltermination of string inside bounds |
| 168 | if (!memchr(bs.peekData(bs.getRemainSize()), 0, bs.getRemainSize())) |
| 169 | break; |
| 170 | std::array<uint32_t, 4> tmp = {{}}; |
| 171 | std::istringstream iss(bs.peekString()); |
| 172 | iss >> tmp[0] >> tmp[1] >> tmp[2] >> tmp[3]; |
| 173 | if (!iss.fail() && tmp[0] > 0 && tmp[1] > 0 && tmp[2] > 0 && |
| 174 | tmp[3] > 0) { |
| 175 | mRaw->metadata.wbCoeffs[0] = static_cast<float>(tmp[0]) / tmp[1]; |
| 176 | mRaw->metadata.wbCoeffs[1] = static_cast<float>(tmp[0]) / tmp[2]; |
| 177 | mRaw->metadata.wbCoeffs[2] = static_cast<float>(tmp[0]) / tmp[3]; |
| 178 | } |
| 179 | break; |
| 180 | } |
| 181 | bs.skipBytes(1); |
| 182 | } |
| 183 | } |
| 184 | } |
| 185 | |
| 186 | } // namespace rawspeed |
nothing calls this directly
no test coverage detected