mirror of
https://github.com/robmcmullen/atrcopy.git
synced 2025-01-04 15:31:01 +00:00
Refs #1: added detection of DCM images
This commit is contained in:
parent
1a7381b865
commit
7659499fdb
@ -20,7 +20,7 @@ from .kboot import KBootImage, add_xexboot_header
|
||||
from .segments import SegmentData, SegmentSaver, DefaultSegment, EmptySegment, ObjSegment, RawSectorsSegment, SegmentedFileSegment, user_bit_mask, match_bit_mask, comment_bit_mask, data_style, selected_bit_mask, diff_bit_mask, not_user_bit_mask, interleave_segments, SegmentList, get_style_mask, get_style_bits
|
||||
from .spartados import SpartaDosDiskImage
|
||||
from .cartridge import A8CartHeader, AtariCartImage
|
||||
from .parsers import SegmentParser, DefaultSegmentParser, guess_parser_for_mime, guess_parser_for_system, iter_parsers, iter_known_segment_parsers, mime_parse_order, parsers_for_filename
|
||||
from .parsers import SegmentParser, DefaultSegmentParser, guess_parser_for_mime, guess_parser_for_system, guess_container, iter_known_segment_parsers, mime_parse_order, parsers_for_filename
|
||||
from .magic import guess_detail_for_mime
|
||||
from .utils import to_numpy, text_to_int
|
||||
|
||||
@ -60,6 +60,11 @@ def find_diskimage(filename):
|
||||
print("Loading file %s" % filename)
|
||||
rawdata = SegmentData(fh.read())
|
||||
parser = None
|
||||
try:
|
||||
unpacked = guess_container(rawdata.data)
|
||||
except errors.UnsupportedContainer as e:
|
||||
print(f"{filename}: {e}")
|
||||
return None
|
||||
for mime in mime_parse_order:
|
||||
if options.verbose:
|
||||
print("Trying MIME type %s" % mime)
|
||||
|
12
atrcopy/container.py
Normal file
12
atrcopy/container.py
Normal file
@ -0,0 +1,12 @@
|
||||
import numpy as np
|
||||
|
||||
from . import errors
|
||||
from .segments import SegmentData
|
||||
|
||||
|
||||
class DiskImageContainer:
|
||||
def __init__(self, data):
|
||||
self.unpacked = self.unpack_raw_data(data)
|
||||
|
||||
def unpack_raw_data(self, data):
|
||||
pass
|
41
atrcopy/dcm.py
Normal file
41
atrcopy/dcm.py
Normal file
@ -0,0 +1,41 @@
|
||||
import numpy as np
|
||||
|
||||
from . import errors
|
||||
from .container import DiskImageContainer
|
||||
from .segments import SegmentData
|
||||
|
||||
|
||||
class DCMContainer(DiskImageContainer):
|
||||
valid_densities = {
|
||||
0: (720, 128),
|
||||
1: (720, 256),
|
||||
2: (1040, 128),
|
||||
}
|
||||
|
||||
def get_next(self):
|
||||
try:
|
||||
data = self.raw[self.index]
|
||||
except IndexError:
|
||||
raise errors.InvalidContainer
|
||||
else:
|
||||
self.index += 1
|
||||
return data
|
||||
|
||||
def unpack_raw_data(self, data):
|
||||
self.index = 0
|
||||
self.count = len(data)
|
||||
self.raw = data
|
||||
archive_type = self.get_next()
|
||||
if archive_type == 0xf9 or archive_type == 0xfa:
|
||||
archive_flags = self.get_next()
|
||||
if archive_flags & 0x1f != 1:
|
||||
if archive_type == 0xf9:
|
||||
raise errors.InvalidContainer("DCM multi-file archive combined in the wrong order")
|
||||
else:
|
||||
raise errors.InvalidContainer("Expected pass one of DCM archive first")
|
||||
density_flag = (archive_flags >> 5) & 3
|
||||
if density_flag not in self.valid_densities:
|
||||
raise errors.InvalidContainer(f"Unsupported density flag {density_flag} in DCM")
|
||||
else:
|
||||
raise errors.InvalidContainer("Not a DCM file")
|
||||
raise errors.UnsupportedContainer("DCM archives are not yet supported")
|
@ -65,3 +65,11 @@ class NotEnoughSpaceOnDisk(AtrError):
|
||||
|
||||
class FileNotFound(AtrError):
|
||||
pass
|
||||
|
||||
|
||||
class UnsupportedContainer(AtrError):
|
||||
pass
|
||||
|
||||
|
||||
class InvalidContainer(AtrError):
|
||||
pass
|
||||
|
@ -10,6 +10,7 @@ from .dos33 import Dos33DiskImage, ProdosDiskImage, Dos33BinFile
|
||||
from .standard_delivery import StandardDeliveryImage
|
||||
from . import errors
|
||||
from .magic import guess_detail_for_mime
|
||||
from .dcm import DCMContainer
|
||||
|
||||
import logging
|
||||
log = logging.getLogger(__name__)
|
||||
@ -157,6 +158,22 @@ class ProdosSegmentParser(SegmentParser):
|
||||
image_type = ProdosDiskImage
|
||||
|
||||
|
||||
known_containers = [
|
||||
DCMContainer,
|
||||
]
|
||||
|
||||
|
||||
def guess_container(r):
|
||||
for c in known_containers:
|
||||
try:
|
||||
found = c(r)
|
||||
except errors.InvalidContainer:
|
||||
continue
|
||||
else:
|
||||
return found
|
||||
return None
|
||||
|
||||
|
||||
def guess_parser_for_mime(mime, r, verbose=False):
|
||||
parsers = mime_parsers[mime]
|
||||
found = None
|
||||
@ -182,6 +199,9 @@ def guess_parser_for_system(mime_base, r):
|
||||
|
||||
|
||||
def iter_parsers(r):
|
||||
container = guess_container(r.data)
|
||||
if container is not None:
|
||||
r = container.unpacked
|
||||
for mime in mime_parse_order:
|
||||
p = guess_parser_for_mime(mime, r)
|
||||
if p is not None:
|
||||
|
Loading…
Reference in New Issue
Block a user