| 19 | ImgImageReader(const ImageReaderProto& config): ImageReader(config) {} |
| 20 | |
| 21 | std::unique_ptr<Image> readImage() override |
| 22 | { |
| 23 | std::ifstream inputFile( |
| 24 | _config.filename(), std::ios::in | std::ios::binary); |
| 25 | if (!inputFile.is_open()) |
| 26 | error("cannot open input file"); |
| 27 | |
| 28 | const auto& layout = globalConfig()->layout(); |
| 29 | if (!layout.tracks() || !layout.sides()) |
| 30 | error( |
| 31 | "IMG: bad configuration; did you remember to set the " |
| 32 | "tracks, sides and trackdata fields in the layout?"); |
| 33 | |
| 34 | const auto diskLayout = createDiskLayout(); |
| 35 | bool in_filesystem_order = _config.img().filesystem_sector_order(); |
| 36 | std::unique_ptr<Image> image(new Image); |
| 37 | |
| 38 | for (auto& logicalLocation : |
| 39 | in_filesystem_order ? diskLayout->logicalLocationsInFilesystemOrder |
| 40 | : diskLayout->logicalLocations) |
| 41 | { |
| 42 | auto& ltl = diskLayout->layoutByLogicalLocation.at(logicalLocation); |
| 43 | |
| 44 | for (unsigned sectorId : in_filesystem_order |
| 45 | ? ltl->filesystemSectorOrder |
| 46 | : ltl->naturalSectorOrder) |
| 47 | { |
| 48 | if (inputFile.eof()) |
| 49 | break; |
| 50 | |
| 51 | Bytes data(ltl->sectorSize); |
| 52 | inputFile.read((char*)data.begin(), data.size()); |
| 53 | |
| 54 | const auto& sector = image->put( |
| 55 | logicalLocation.cylinder, logicalLocation.head, sectorId); |
| 56 | sector->status = Sector::OK; |
| 57 | sector->data = data; |
| 58 | } |
| 59 | } |
| 60 | |
| 61 | image->calculateSize(); |
| 62 | const Geometry& geometry = image->getGeometry(); |
| 63 | log("IMG: read {} tracks, {} sides, {} kB total from {}", |
| 64 | geometry.numCylinders, |
| 65 | geometry.numHeads, |
| 66 | inputFile.tellg() / 1024, |
| 67 | _config.filename()); |
| 68 | return image; |
| 69 | } |
| 70 | }; |
| 71 | |
| 72 | std::unique_ptr<ImageReader> ImageReader::createImgImageReader( |
no test coverage detected