| 121 | } |
| 122 | |
| 123 | void CrwDecoder::decodeMetaDataInternal(const CameraMetaData* meta) { |
| 124 | int iso = 0; |
| 125 | mRaw->cfa.setCFA(iPoint2D(2,2), CFA_RED, CFA_GREEN, CFA_GREEN, CFA_BLUE); |
| 126 | vector<const CiffIFD*> data = mRootIFD->getIFDsWithTag(CIFF_MAKEMODEL); |
| 127 | if (data.empty()) |
| 128 | ThrowRDE("Model name not found"); |
| 129 | vector<string> makemodel = data[0]->getEntry(CIFF_MAKEMODEL)->getStrings(); |
| 130 | if (makemodel.size() < 2) |
| 131 | ThrowRDE("wrong number of strings for make/model"); |
| 132 | string make = makemodel[0]; |
| 133 | string model = makemodel[1]; |
| 134 | string mode; |
| 135 | |
| 136 | if (mRootIFD->hasEntryRecursive(CIFF_SHOTINFO)) { |
| 137 | const CiffEntry* shot_info = mRootIFD->getEntryRecursive(CIFF_SHOTINFO); |
| 138 | if (shot_info->type == CIFF_SHORT && shot_info->count >= 2) { |
| 139 | // os << exp(canonEv(value.toLong()) * log(2.0)) * 100.0 / 32.0; |
| 140 | uint16_t iso_index = shot_info->getU16(2); |
| 141 | iso = expf(canonEv(static_cast<int64_t>(iso_index)) * logf(2.0)) * |
| 142 | 100.0F / 32.0F; |
| 143 | } |
| 144 | } |
| 145 | |
| 146 | // Fetch the white balance |
| 147 | try{ |
| 148 | if (mRootIFD->hasEntryRecursive(static_cast<CiffTag>(0x0032))) { |
| 149 | const CiffEntry* wb = |
| 150 | mRootIFD->getEntryRecursive(static_cast<CiffTag>(0x0032)); |
| 151 | if (wb->type == CIFF_BYTE && wb->count == 768) { |
| 152 | // We're in a D30 file, values are RGGB |
| 153 | // This, not 0x102c tag, should be used. |
| 154 | std::array<uint16_t, 4> wbMuls{ |
| 155 | {wb->getU16(36), wb->getU16(37), wb->getU16(38), wb->getU16(39)}}; |
| 156 | for (const auto& mul : wbMuls) { |
| 157 | if (0 == mul) |
| 158 | ThrowRDE("WB coeffient is zero!"); |
| 159 | } |
| 160 | |
| 161 | mRaw->metadata.wbCoeffs[0] = static_cast<float>(1024.0 / wbMuls[0]); |
| 162 | mRaw->metadata.wbCoeffs[1] = |
| 163 | static_cast<float>((1024.0 / wbMuls[1]) + (1024.0 / wbMuls[2])) / |
| 164 | 2.0F; |
| 165 | mRaw->metadata.wbCoeffs[2] = static_cast<float>(1024.0 / wbMuls[3]); |
| 166 | } else if (wb->type == CIFF_BYTE && wb->count > 768) { // Other G series and S series cameras |
| 167 | // correct offset for most cameras |
| 168 | int offset = hints.get("wb_offset", 120); |
| 169 | |
| 170 | std::array<uint16_t, 2> key = {{0x410, 0x45f3}}; |
| 171 | if (! hints.has("wb_mangle")) |
| 172 | key[0] = key[1] = 0; |
| 173 | |
| 174 | offset /= 2; |
| 175 | mRaw->metadata.wbCoeffs[0] = |
| 176 | static_cast<float>(wb->getU16(offset + 1) ^ key[1]); |
| 177 | mRaw->metadata.wbCoeffs[1] = |
| 178 | static_cast<float>(wb->getU16(offset + 0) ^ key[0]); |
| 179 | mRaw->metadata.wbCoeffs[2] = |
| 180 | static_cast<float>(wb->getU16(offset + 2) ^ key[0]); |
nothing calls this directly
no test coverage detected