| 189 | } |
| 190 | |
| 191 | void RafDecoder::decodeMetaDataInternal(const CameraMetaData* meta) { |
| 192 | int iso = 0; |
| 193 | if (mRootIFD->hasEntryRecursive(ISOSPEEDRATINGS)) |
| 194 | iso = mRootIFD->getEntryRecursive(ISOSPEEDRATINGS)->getU32(); |
| 195 | mRaw->metadata.isoSpeed = iso; |
| 196 | |
| 197 | // This is where we'd normally call setMetaData but since we may still need |
| 198 | // to rotate the image for SuperCCD cameras we do everything ourselves |
| 199 | auto id = mRootIFD->getID(); |
| 200 | const Camera* cam = meta->getCamera(id.make, id.model, mRaw->metadata.mode); |
| 201 | if (!cam) |
| 202 | ThrowRDE("Couldn't find camera"); |
| 203 | |
| 204 | assert(cam != nullptr); |
| 205 | |
| 206 | iPoint2D new_size(mRaw->dim); |
| 207 | iPoint2D crop_offset = iPoint2D(0,0); |
| 208 | |
| 209 | if (applyCrop) { |
| 210 | new_size = cam->cropSize; |
| 211 | crop_offset = cam->cropPos; |
| 212 | bool double_width = hints.has("double_width_unpacked"); |
| 213 | // If crop size is negative, use relative cropping |
| 214 | if (new_size.x <= 0) |
| 215 | new_size.x = mRaw->dim.x / (double_width ? 2 : 1) - cam->cropPos.x + new_size.x; |
| 216 | else |
| 217 | new_size.x /= (double_width ? 2 : 1); |
| 218 | if (new_size.y <= 0) |
| 219 | new_size.y = mRaw->dim.y - cam->cropPos.y + new_size.y; |
| 220 | } |
| 221 | |
| 222 | bool rotate = hints.has("fuji_rotate"); |
| 223 | rotate = rotate && fujiRotate; |
| 224 | |
| 225 | // Rotate 45 degrees - could be multithreaded. |
| 226 | if (rotate && !this->uncorrectedRawValues) { |
| 227 | // Calculate the 45 degree rotated size; |
| 228 | uint32_t rotatedsize; |
| 229 | uint32_t rotationPos; |
| 230 | if (alt_layout) { |
| 231 | rotatedsize = new_size.y+new_size.x/2; |
| 232 | rotationPos = new_size.x/2 - 1; |
| 233 | } |
| 234 | else { |
| 235 | rotatedsize = new_size.x+new_size.y/2; |
| 236 | rotationPos = new_size.x - 1; |
| 237 | } |
| 238 | |
| 239 | iPoint2D final_size(rotatedsize, rotatedsize-1); |
| 240 | RawImage rotated = RawImage::create(final_size, TYPE_USHORT16, 1); |
| 241 | rotated->clearArea(iRectangle2D(iPoint2D(0,0), rotated->dim)); |
| 242 | rotated->metadata = mRaw->metadata; |
| 243 | rotated->metadata.fujiRotationPos = rotationPos; |
| 244 | |
| 245 | int dest_pitch = static_cast<int>(rotated->pitch) / 2; |
| 246 | auto* dst = reinterpret_cast<uint16_t*>(rotated->getData(0, 0)); |
| 247 | |
| 248 | for (int y = 0; y < new_size.y; y++) { |
nothing calls this directly
no test coverage detected