Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/imageio-2.35.1-py3.8.egg/imageio/plugins/lytro.py: 24%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

306 statements  

1# -*- coding: utf-8 -*- 

2# Copyright (c) 2018, imageio contributors 

3# imageio is distributed under the terms of the (new) BSD License. 

4# 

5 

6""" Read LFR files (Lytro Illum). 

7 

8Backend: internal 

9 

10Plugin to read Lytro Illum .lfr and .raw files as produced 

11by the Lytro Illum light field camera. It is actually a collection 

12of plugins, each supporting slightly different keyword arguments 

13 

14Parameters 

15---------- 

16meta_only : bool 

17 Whether to only read the metadata. 

18include_thumbnail : bool 

19 (only for lytro-lfr and lytro-lfp) 

20 Whether to include an image thumbnail in the metadata. 

21 

22""" 

23# 

24# 

25# This code is based on work by 

26# David Uhlig and his lfr_reader 

27# (https://www.iiit.kit.edu/uhlig.php) 

28# Donald Dansereau and his Matlab LF Toolbox 

29# (http://dgd.vision/Tools/LFToolbox/) 

30# and Behnam Esfahbod and his Python LFP-Reader 

31# (https://github.com/behnam/python-lfp-reader/) 

32 

33 

34import os 

35import json 

36import struct 

37import logging 

38 

39 

40import numpy as np 

41 

42from ..core import Format 

43from ..v2 import imread 

44 

45 

46logger = logging.getLogger(__name__) 

47 

48 

49# Sensor size of Lytro Illum resp. Lytro F01 light field camera sensor 

50LYTRO_ILLUM_IMAGE_SIZE = (5368, 7728) 

51LYTRO_F01_IMAGE_SIZE = (3280, 3280) 

52 

53# Parameter of lfr file format 

54HEADER_LENGTH = 12 

55SIZE_LENGTH = 4 # = 16 - header_length 

56SHA1_LENGTH = 45 # = len("sha1-") + (160 / 4) 

57PADDING_LENGTH = 35 # = (4*16) - header_length - size_length - sha1_length 

58DATA_CHUNKS_ILLUM = 11 

59DATA_CHUNKS_F01 = 3 

60 

61 

62class LytroFormat(Format): 

63 """Base class for Lytro format. 

64 The subclasses LytroLfrFormat, LytroLfpFormat, LytroIllumRawFormat and 

65 LytroF01RawFormat implement the Lytro-LFR, Lytro-LFP and Lytro-RAW format 

66 for the Illum and original F01 camera respectively. 

67 Writing is not supported. 

68 """ 

69 

70 # Only single images are supported. 

71 _modes = "i" 

72 

73 def _can_write(self, request): 

74 # Writing of Lytro files is not supported 

75 return False 

76 

77 # -- writer 

78 

79 class Writer(Format.Writer): 

80 def _open(self, flags=0): 

81 self._fp = self.request.get_file() 

82 

83 def _close(self): 

84 # Close the reader. 

85 # Note that the request object will close self._fp 

86 pass 

87 

88 def _append_data(self, im, meta): 

89 # Process the given data and meta data. 

90 raise RuntimeError("The lytro format cannot write image data.") 

91 

92 def _set_meta_data(self, meta): 

93 # Process the given meta data (global for all images) 

94 # It is not mandatory to support this. 

95 raise RuntimeError("The lytro format cannot write meta data.") 

96 

97 

98class LytroIllumRawFormat(LytroFormat): 

99 """This is the Lytro Illum RAW format. 

100 The raw format is a 10bit image format as used by the Lytro Illum 

101 light field camera. The format will read the specified raw file and will 

102 try to load a .txt or .json file with the associated meta data. 

103 This format does not support writing. 

104 

105 

106 Parameters for reading 

107 ---------------------- 

108 meta_only : bool 

109 Whether to only read the metadata. 

110 """ 

111 

112 def _can_read(self, request): 

113 # Check if mode and extensions are supported by the format 

114 if request.extension in (".raw",): 

115 return True 

116 

117 @staticmethod 

118 def rearrange_bits(array): 

119 # Do bit rearrangement for the 10-bit lytro raw format 

120 # Normalize output to 1.0 as float64 

121 t0 = array[0::5] 

122 t1 = array[1::5] 

123 t2 = array[2::5] 

124 t3 = array[3::5] 

125 lsb = array[4::5] 

126 

127 t0 = np.left_shift(t0, 2) + np.bitwise_and(lsb, 3) 

128 t1 = np.left_shift(t1, 2) + np.right_shift(np.bitwise_and(lsb, 12), 2) 

129 t2 = np.left_shift(t2, 2) + np.right_shift(np.bitwise_and(lsb, 48), 4) 

130 t3 = np.left_shift(t3, 2) + np.right_shift(np.bitwise_and(lsb, 192), 6) 

131 

132 image = np.zeros(LYTRO_ILLUM_IMAGE_SIZE, dtype=np.uint16) 

133 image[:, 0::4] = t0.reshape( 

134 (LYTRO_ILLUM_IMAGE_SIZE[0], LYTRO_ILLUM_IMAGE_SIZE[1] // 4) 

135 ) 

136 image[:, 1::4] = t1.reshape( 

137 (LYTRO_ILLUM_IMAGE_SIZE[0], LYTRO_ILLUM_IMAGE_SIZE[1] // 4) 

138 ) 

139 image[:, 2::4] = t2.reshape( 

140 (LYTRO_ILLUM_IMAGE_SIZE[0], LYTRO_ILLUM_IMAGE_SIZE[1] // 4) 

141 ) 

142 image[:, 3::4] = t3.reshape( 

143 (LYTRO_ILLUM_IMAGE_SIZE[0], LYTRO_ILLUM_IMAGE_SIZE[1] // 4) 

144 ) 

145 

146 # Normalize data to 1.0 as 64-bit float. 

147 # Division is by 1023 as the Lytro Illum saves 10-bit raw data. 

148 return np.divide(image, 1023.0).astype(np.float64) 

149 

150 # -- reader 

151 

152 class Reader(Format.Reader): 

153 def _open(self, meta_only=False): 

154 self._file = self.request.get_file() 

155 self._data = None 

156 self._meta_only = meta_only 

157 

158 def _close(self): 

159 # Close the reader. 

160 # Note that the request object will close self._file 

161 del self._data 

162 

163 def _get_length(self): 

164 # Return the number of images. 

165 return 1 

166 

167 def _get_data(self, index): 

168 # Return the data and meta data for the given index 

169 

170 if index not in [0, "None"]: 

171 raise IndexError("Lytro file contains only one dataset") 

172 

173 if not self._meta_only: 

174 # Read all bytes 

175 if self._data is None: 

176 self._data = self._file.read() 

177 

178 # Read bytes from string and convert to uint16 

179 raw = np.frombuffer(self._data, dtype=np.uint8).astype(np.uint16) 

180 

181 # Rearrange bits 

182 img = LytroIllumRawFormat.rearrange_bits(raw) 

183 

184 else: 

185 # Return empty image 

186 img = np.array([]) 

187 

188 # Return image and meta data 

189 return img, self._get_meta_data(index=0) 

190 

191 def _get_meta_data(self, index): 

192 # Get the meta data for the given index. If index is None, it 

193 # should return the global meta data. 

194 

195 if index not in [0, None]: 

196 raise IndexError("Lytro meta data file contains only one dataset") 

197 

198 # Try to read meta data from meta data file corresponding 

199 # to the raw data file, extension in [.txt, .TXT, .json, .JSON] 

200 filename_base = os.path.splitext(self.request.get_local_filename())[0] 

201 

202 meta_data = None 

203 

204 for ext in [".txt", ".TXT", ".json", ".JSON"]: 

205 if os.path.isfile(filename_base + ext): 

206 meta_data = json.load(open(filename_base + ext)) 

207 

208 if meta_data is not None: 

209 return meta_data 

210 

211 else: 

212 logger.warning("No metadata file found for provided raw file.") 

213 return {} 

214 

215 

216class LytroLfrFormat(LytroFormat): 

217 """This is the Lytro Illum LFR format. 

218 The lfr is a image and meta data container format as used by the 

219 Lytro Illum light field camera. 

220 The format will read the specified lfr file. 

221 This format does not support writing. 

222 

223 Parameters for reading 

224 ---------------------- 

225 meta_only : bool 

226 Whether to only read the metadata. 

227 include_thumbnail : bool 

228 Whether to include an image thumbnail in the metadata. 

229 """ 

230 

231 def _can_read(self, request): 

232 # Check if mode and extensions are supported by the format 

233 if request.extension in (".lfr",): 

234 return True 

235 

236 # -- reader 

237 

238 class Reader(Format.Reader): 

239 def _open(self, meta_only=False, include_thumbnail=True): 

240 self._file = self.request.get_file() 

241 self._data = None 

242 self._chunks = {} 

243 self.metadata = {} 

244 self._content = None 

245 self._meta_only = meta_only 

246 self._include_thumbnail = include_thumbnail 

247 

248 self._find_header() 

249 self._find_chunks() 

250 self._find_meta() 

251 

252 try: 

253 # Get sha1 dict and check if it is in dictionary of data chunks 

254 chunk_dict = self._content["frames"][0]["frame"] 

255 if ( 

256 chunk_dict["metadataRef"] in self._chunks 

257 and chunk_dict["imageRef"] in self._chunks 

258 and chunk_dict["privateMetadataRef"] in self._chunks 

259 ): 

260 if not self._meta_only: 

261 # Read raw image data byte buffer 

262 data_pos, size = self._chunks[chunk_dict["imageRef"]] 

263 self._file.seek(data_pos, 0) 

264 self.raw_image_data = self._file.read(size) 

265 

266 # Read meta data 

267 data_pos, size = self._chunks[chunk_dict["metadataRef"]] 

268 self._file.seek(data_pos, 0) 

269 metadata = self._file.read(size) 

270 # Add metadata to meta data dict 

271 self.metadata["metadata"] = json.loads(metadata.decode("ASCII")) 

272 

273 # Read private metadata 

274 data_pos, size = self._chunks[chunk_dict["privateMetadataRef"]] 

275 self._file.seek(data_pos, 0) 

276 serial_numbers = self._file.read(size) 

277 self.serial_numbers = json.loads(serial_numbers.decode("ASCII")) 

278 # Add private metadata to meta data dict 

279 self.metadata["privateMetadata"] = self.serial_numbers 

280 

281 # Read image preview thumbnail 

282 if self._include_thumbnail: 

283 chunk_dict = self._content["thumbnails"][0] 

284 if chunk_dict["imageRef"] in self._chunks: 

285 # Read thumbnail image from thumbnail chunk 

286 data_pos, size = self._chunks[chunk_dict["imageRef"]] 

287 self._file.seek(data_pos, 0) 

288 # Read binary data, read image as jpeg 

289 thumbnail_data = self._file.read(size) 

290 thumbnail_img = imread(thumbnail_data, format="jpeg") 

291 

292 thumbnail_height = chunk_dict["height"] 

293 thumbnail_width = chunk_dict["width"] 

294 

295 # Add thumbnail to metadata 

296 self.metadata["thumbnail"] = { 

297 "image": thumbnail_img, 

298 "height": thumbnail_height, 

299 "width": thumbnail_width, 

300 } 

301 

302 except KeyError: 

303 raise RuntimeError("The specified file is not a valid LFR file.") 

304 

305 def _close(self): 

306 # Close the reader. 

307 # Note that the request object will close self._file 

308 del self._data 

309 

310 def _get_length(self): 

311 # Return the number of images. Can be np.inf 

312 return 1 

313 

314 def _find_header(self): 

315 """ 

316 Checks if file has correct header and skip it. 

317 """ 

318 file_header = b"\x89LFP\x0D\x0A\x1A\x0A\x00\x00\x00\x01" 

319 # Read and check header of file 

320 header = self._file.read(HEADER_LENGTH) 

321 if header != file_header: 

322 raise RuntimeError("The LFR file header is invalid.") 

323 

324 # Read first bytes to skip header 

325 self._file.read(SIZE_LENGTH) 

326 

327 def _find_chunks(self): 

328 """ 

329 Gets start position and size of data chunks in file. 

330 """ 

331 chunk_header = b"\x89LFC\x0D\x0A\x1A\x0A\x00\x00\x00\x00" 

332 

333 for i in range(0, DATA_CHUNKS_ILLUM): 

334 data_pos, size, sha1 = self._get_chunk(chunk_header) 

335 self._chunks[sha1] = (data_pos, size) 

336 

337 def _find_meta(self): 

338 """ 

339 Gets a data chunk that contains information over content 

340 of other data chunks. 

341 """ 

342 meta_header = b"\x89LFM\x0D\x0A\x1A\x0A\x00\x00\x00\x00" 

343 data_pos, size, sha1 = self._get_chunk(meta_header) 

344 

345 # Get content 

346 self._file.seek(data_pos, 0) 

347 data = self._file.read(size) 

348 self._content = json.loads(data.decode("ASCII")) 

349 

350 def _get_chunk(self, header): 

351 """ 

352 Checks if chunk has correct header and skips it. 

353 Finds start position and length of next chunk and reads 

354 sha1-string that identifies the following data chunk. 

355 

356 Parameters 

357 ---------- 

358 header : bytes 

359 Byte string that identifies start of chunk. 

360 

361 Returns 

362 ------- 

363 data_pos : int 

364 Start position of data chunk in file. 

365 size : int 

366 Size of data chunk. 

367 sha1 : str 

368 Sha1 value of chunk. 

369 """ 

370 # Read and check header of chunk 

371 header_chunk = self._file.read(HEADER_LENGTH) 

372 if header_chunk != header: 

373 raise RuntimeError("The LFR chunk header is invalid.") 

374 

375 data_pos = None 

376 sha1 = None 

377 

378 # Read size 

379 size = struct.unpack(">i", self._file.read(SIZE_LENGTH))[0] 

380 if size > 0: 

381 # Read sha1 

382 sha1 = str(self._file.read(SHA1_LENGTH).decode("ASCII")) 

383 # Skip fixed null chars 

384 self._file.read(PADDING_LENGTH) 

385 # Find start of data and skip data 

386 data_pos = self._file.tell() 

387 self._file.seek(size, 1) 

388 # Skip extra null chars 

389 ch = self._file.read(1) 

390 while ch == b"\0": 

391 ch = self._file.read(1) 

392 self._file.seek(-1, 1) 

393 

394 return data_pos, size, sha1 

395 

396 def _get_data(self, index): 

397 # Return the data and meta data for the given index 

398 if index not in [0, None]: 

399 raise IndexError("Lytro lfr file contains only one dataset") 

400 

401 if not self._meta_only: 

402 # Read bytes from string and convert to uint16 

403 raw = np.frombuffer(self.raw_image_data, dtype=np.uint8).astype( 

404 np.uint16 

405 ) 

406 im = LytroIllumRawFormat.rearrange_bits(raw) 

407 else: 

408 im = np.array([]) 

409 

410 # Return array and dummy meta data 

411 return im, self.metadata 

412 

413 def _get_meta_data(self, index): 

414 # Get the meta data for the given index. If index is None, 

415 # it returns the global meta data. 

416 if index not in [0, None]: 

417 raise IndexError("Lytro meta data file contains only one dataset") 

418 

419 return self.metadata 

420 

421 

422class LytroF01RawFormat(LytroFormat): 

423 """This is the Lytro RAW format for the original F01 Lytro camera. 

424 The raw format is a 12bit image format as used by the Lytro F01 

425 light field camera. The format will read the specified raw file and will 

426 try to load a .txt or .json file with the associated meta data. 

427 This format does not support writing. 

428 

429 

430 Parameters for reading 

431 ---------------------- 

432 meta_only : bool 

433 Whether to only read the metadata. 

434 

435 """ 

436 

437 def _can_read(self, request): 

438 # Check if mode and extensions are supported by the format 

439 if request.extension in (".raw",): 

440 return True 

441 

442 @staticmethod 

443 def rearrange_bits(array): 

444 # Do bit rearrangement for the 12-bit lytro raw format 

445 # Normalize output to 1.0 as float64 

446 t0 = array[0::3] 

447 t1 = array[1::3] 

448 t2 = array[2::3] 

449 

450 a0 = np.left_shift(t0, 4) + np.right_shift(np.bitwise_and(t1, 240), 4) 

451 a1 = np.left_shift(np.bitwise_and(t1, 15), 8) + t2 

452 

453 image = np.zeros(LYTRO_F01_IMAGE_SIZE, dtype=np.uint16) 

454 image[:, 0::2] = a0.reshape( 

455 (LYTRO_F01_IMAGE_SIZE[0], LYTRO_F01_IMAGE_SIZE[1] // 2) 

456 ) 

457 image[:, 1::2] = a1.reshape( 

458 (LYTRO_F01_IMAGE_SIZE[0], LYTRO_F01_IMAGE_SIZE[1] // 2) 

459 ) 

460 

461 # Normalize data to 1.0 as 64-bit float. 

462 # Division is by 4095 as the Lytro F01 saves 12-bit raw data. 

463 return np.divide(image, 4095.0).astype(np.float64) 

464 

465 # -- reader 

466 

467 class Reader(Format.Reader): 

468 def _open(self, meta_only=False): 

469 self._file = self.request.get_file() 

470 self._data = None 

471 self._meta_only = meta_only 

472 

473 def _close(self): 

474 # Close the reader. 

475 # Note that the request object will close self._file 

476 del self._data 

477 

478 def _get_length(self): 

479 # Return the number of images. 

480 return 1 

481 

482 def _get_data(self, index): 

483 # Return the data and meta data for the given index 

484 

485 if index not in [0, "None"]: 

486 raise IndexError("Lytro file contains only one dataset") 

487 

488 if not self._meta_only: 

489 # Read all bytes 

490 if self._data is None: 

491 self._data = self._file.read() 

492 

493 # Read bytes from string and convert to uint16 

494 raw = np.frombuffer(self._data, dtype=np.uint8).astype(np.uint16) 

495 

496 # Rearrange bits 

497 img = LytroF01RawFormat.rearrange_bits(raw) 

498 

499 else: 

500 img = np.array([]) 

501 

502 # Return image and meta data 

503 return img, self._get_meta_data(index=0) 

504 

505 def _get_meta_data(self, index): 

506 # Get the meta data for the given index. If index is None, it 

507 # should return the global meta data. 

508 

509 if index not in [0, None]: 

510 raise IndexError("Lytro meta data file contains only one dataset") 

511 

512 # Try to read meta data from meta data file corresponding 

513 # to the raw data file, extension in [.txt, .TXT, .json, .JSON] 

514 filename_base = os.path.splitext(self.request.get_local_filename())[0] 

515 

516 meta_data = None 

517 

518 for ext in [".txt", ".TXT", ".json", ".JSON"]: 

519 if os.path.isfile(filename_base + ext): 

520 meta_data = json.load(open(filename_base + ext)) 

521 

522 if meta_data is not None: 

523 return meta_data 

524 

525 else: 

526 logger.warning("No metadata file found for provided raw file.") 

527 return {} 

528 

529 

530class LytroLfpFormat(LytroFormat): 

531 """This is the Lytro Illum LFP format. 

532 The lfp is a image and meta data container format as used by the 

533 Lytro F01 light field camera. 

534 The format will read the specified lfp file. 

535 This format does not support writing. 

536 

537 Parameters for reading 

538 ---------------------- 

539 meta_only : bool 

540 Whether to only read the metadata. 

541 include_thumbnail : bool 

542 Whether to include an image thumbnail in the metadata. 

543 """ 

544 

545 def _can_read(self, request): 

546 # Check if mode and extensions are supported by the format 

547 if request.extension in (".lfp",): 

548 return True 

549 

550 # -- reader 

551 

552 class Reader(Format.Reader): 

553 def _open(self, meta_only=False): 

554 self._file = self.request.get_file() 

555 self._data = None 

556 self._chunks = {} 

557 self.metadata = {} 

558 self._content = None 

559 self._meta_only = meta_only 

560 

561 self._find_header() 

562 self._find_meta() 

563 self._find_chunks() 

564 

565 try: 

566 # Get sha1 dict and check if it is in dictionary of data chunks 

567 chunk_dict = self._content["picture"]["frameArray"][0]["frame"] 

568 if ( 

569 chunk_dict["metadataRef"] in self._chunks 

570 and chunk_dict["imageRef"] in self._chunks 

571 and chunk_dict["privateMetadataRef"] in self._chunks 

572 ): 

573 if not self._meta_only: 

574 # Read raw image data byte buffer 

575 data_pos, size = self._chunks[chunk_dict["imageRef"]] 

576 self._file.seek(data_pos, 0) 

577 self.raw_image_data = self._file.read(size) 

578 

579 # Read meta data 

580 data_pos, size = self._chunks[chunk_dict["metadataRef"]] 

581 self._file.seek(data_pos, 0) 

582 metadata = self._file.read(size) 

583 # Add metadata to meta data dict 

584 self.metadata["metadata"] = json.loads(metadata.decode("ASCII")) 

585 

586 # Read private metadata 

587 data_pos, size = self._chunks[chunk_dict["privateMetadataRef"]] 

588 self._file.seek(data_pos, 0) 

589 serial_numbers = self._file.read(size) 

590 self.serial_numbers = json.loads(serial_numbers.decode("ASCII")) 

591 # Add private metadata to meta data dict 

592 self.metadata["privateMetadata"] = self.serial_numbers 

593 

594 except KeyError: 

595 raise RuntimeError("The specified file is not a valid LFP file.") 

596 

597 def _close(self): 

598 # Close the reader. 

599 # Note that the request object will close self._file 

600 del self._data 

601 

602 def _get_length(self): 

603 # Return the number of images. Can be np.inf 

604 return 1 

605 

606 def _find_header(self): 

607 """ 

608 Checks if file has correct header and skip it. 

609 """ 

610 file_header = b"\x89LFP\x0D\x0A\x1A\x0A\x00\x00\x00\x01" 

611 

612 # Read and check header of file 

613 header = self._file.read(HEADER_LENGTH) 

614 if header != file_header: 

615 raise RuntimeError("The LFP file header is invalid.") 

616 

617 # Read first bytes to skip header 

618 self._file.read(SIZE_LENGTH) 

619 

620 def _find_chunks(self): 

621 """ 

622 Gets start position and size of data chunks in file. 

623 """ 

624 chunk_header = b"\x89LFC\x0D\x0A\x1A\x0A\x00\x00\x00\x00" 

625 

626 for i in range(0, DATA_CHUNKS_F01): 

627 data_pos, size, sha1 = self._get_chunk(chunk_header) 

628 self._chunks[sha1] = (data_pos, size) 

629 

630 def _find_meta(self): 

631 """ 

632 Gets a data chunk that contains information over content 

633 of other data chunks. 

634 """ 

635 meta_header = b"\x89LFM\x0D\x0A\x1A\x0A\x00\x00\x00\x00" 

636 

637 data_pos, size, sha1 = self._get_chunk(meta_header) 

638 

639 # Get content 

640 self._file.seek(data_pos, 0) 

641 data = self._file.read(size) 

642 self._content = json.loads(data.decode("ASCII")) 

643 data = self._file.read(5) # Skip 5 

644 

645 def _get_chunk(self, header): 

646 """ 

647 Checks if chunk has correct header and skips it. 

648 Finds start position and length of next chunk and reads 

649 sha1-string that identifies the following data chunk. 

650 

651 Parameters 

652 ---------- 

653 header : bytes 

654 Byte string that identifies start of chunk. 

655 

656 Returns 

657 ------- 

658 data_pos : int 

659 Start position of data chunk in file. 

660 size : int 

661 Size of data chunk. 

662 sha1 : str 

663 Sha1 value of chunk. 

664 """ 

665 # Read and check header of chunk 

666 header_chunk = self._file.read(HEADER_LENGTH) 

667 if header_chunk != header: 

668 raise RuntimeError("The LFP chunk header is invalid.") 

669 

670 data_pos = None 

671 sha1 = None 

672 

673 # Read size 

674 size = struct.unpack(">i", self._file.read(SIZE_LENGTH))[0] 

675 if size > 0: 

676 # Read sha1 

677 sha1 = str(self._file.read(SHA1_LENGTH).decode("ASCII")) 

678 # Skip fixed null chars 

679 self._file.read(PADDING_LENGTH) 

680 # Find start of data and skip data 

681 data_pos = self._file.tell() 

682 self._file.seek(size, 1) 

683 # Skip extra null chars 

684 ch = self._file.read(1) 

685 while ch == b"\0": 

686 ch = self._file.read(1) 

687 self._file.seek(-1, 1) 

688 

689 return data_pos, size, sha1 

690 

691 def _get_data(self, index): 

692 # Return the data and meta data for the given index 

693 if index not in [0, None]: 

694 raise IndexError("Lytro lfp file contains only one dataset") 

695 

696 if not self._meta_only: 

697 # Read bytes from string and convert to uint16 

698 raw = np.frombuffer(self.raw_image_data, dtype=np.uint8).astype( 

699 np.uint16 

700 ) 

701 im = LytroF01RawFormat.rearrange_bits(raw) 

702 else: 

703 im = np.array([]) 

704 

705 # Return array and dummy meta data 

706 return im, self.metadata 

707 

708 def _get_meta_data(self, index): 

709 # Get the meta data for the given index. If index is None, 

710 # it returns the global meta data. 

711 if index not in [0, None]: 

712 raise IndexError("Lytro meta data file contains only one dataset") 

713 

714 return self.metadata