- return m_parent->read_bytes(uint64_t(blockoffs) * uint64_t(m_parent->unit_bytes()), dest, m_hunkbytes);
-#endif
- return CHDERR_DECOMPRESSION_ERROR;
+ UINT8 units_in_hunk = chd->header.hunkbytes / chd->header.unitbytes;
+
+ /* blockoffs is aligned to units_in_hunk */
+ if (blockoffs % units_in_hunk == 0) {
+ return hunk_read_into_memory(chd->parent, blockoffs / units_in_hunk, dest);
+ /* blockoffs is not aligned to units_in_hunk */
+ } else {
+ UINT32 unit_in_hunk = blockoffs % units_in_hunk;
+ UINT8 *buf = malloc(chd->header.hunkbytes);
+ /* Read first half of hunk which contains blockoffs */
+ err = hunk_read_into_memory(chd->parent, blockoffs / units_in_hunk, buf);
+ if (err != CHDERR_NONE) {
+ free(buf);
+ return err;
+ }
+ memcpy(dest, buf + unit_in_hunk * chd->header.unitbytes, (units_in_hunk - unit_in_hunk) * chd->header.unitbytes);
+ /* Read second half of hunk which contains blockoffs */
+ err = hunk_read_into_memory(chd->parent, (blockoffs / units_in_hunk) + 1, buf);
+ if (err != CHDERR_NONE) {
+ free(buf);
+ return err;
+ }
+ memcpy(dest + (units_in_hunk - unit_in_hunk) * chd->header.unitbytes, buf, unit_in_hunk * chd->header.unitbytes);
+ free(buf);
+ }