diff --git a/ijroi/ijroi.py b/ijroi/ijroi.py index 9037096..e272658 100644 --- a/ijroi/ijroi.py +++ b/ijroi/ijroi.py @@ -62,19 +62,17 @@ def getfloat(): v = np.int32(get32()) return v.view(np.float32) + #=========================================================================== + #Read Header data + magic = fileobj.read(4) - if magic != b'Iout': - raise ValueError('Magic number not found') version = get16() # It seems that the roi type field occupies 2 Bytes, but only one is used roi_type = get8() # Discard second Byte: get8() - - if roi_type not in [RoiType.FREEHAND, RoiType.POLYGON, RoiType.RECT, RoiType.POINT]: - raise NotImplementedError('roireader: ROI type %s not supported' % roi_type) - + top = get16() left = get16() bottom = get16() @@ -89,8 +87,7 @@ def getfloat(): stroke_color = get32() fill_color = get32() subtype = get16() - if subtype != 0: - raise NotImplementedError('roireader: ROI subtype %s not supported (!= 0)' % subtype) + options = get16() arrow_style = get8() arrow_head_size = get8() @@ -98,8 +95,57 @@ def getfloat(): position = get32() header2offset = get32() + # End Header data + #=========================================================================== + + #RoiDecoder.java#L177 + subPixelResolution = ((options&SUB_PIXEL_RESOLUTION)!=0) and (version>=222) + + # Check exceptions + if magic != b'Iout': + raise ValueError('Magic number not found') + + if roi_type not in [RoiType.FREEHAND, RoiType.TRACED, RoiType.POLYGON, RoiType.RECT, RoiType.POINT]: + raise NotImplementedError('roireader: ROI type %s not supported' % roi_type) + + if subtype != 0: + raise NotImplementedError('roireader: ROI subtype %s not supported (!= 0)' % subtype) + + #Composite ROI + if shape_roi_size > 0: + coords_bytes = fileobj.read() + buffer = np.frombuffer(coords_bytes, dtype='>f4', count=shape_roi_size) + + segments = [] + + # the number of units to read depens on the type of segement... + # this only works with basic line segemnts (ie type 1, type 2 is quadratic + # and type 3 is cubic + + rc = {4:1, 0:3, 1:3, 2:5, 3:7} + + # scrolls through the buffer one line segment at a time, + # line segments are stored as x,y tuples, I reverse the + # segment, in order to remain consitant with the other return types + i = 0 + these_points = [] + while i < buffer.size: + _type = buffer[i] + read_len = rc[_type] + seg = buffer[i+1:i+read_len] + if seg.size == 0: + segments.append(np.r_[these_points]) + these_points = [] + + else: + these_points.append(seg[::-1]) + + i = i+read_len + + return segments + if roi_type == RoiType.RECT: - if options & SUB_PIXEL_RESOLUTION: + if subPixelResolution: return np.array( [[y1, x1], [y1, x1+x2], [y1+y2, x1+x2], [y1+y2, x1]], dtype=np.float32) @@ -108,7 +154,7 @@ def getfloat(): [[top, left], [top, right], [bottom, right], [bottom, left]], dtype=np.int16) - if options & SUB_PIXEL_RESOLUTION: + if subPixelResolution: getc = getfloat points = np.empty((n_coordinates, 2), dtype=np.float32) fileobj.seek(4*n_coordinates, 1) @@ -119,7 +165,7 @@ def getfloat(): points[:, 1] = [getc() for i in range(n_coordinates)] points[:, 0] = [getc() for i in range(n_coordinates)] - if options & SUB_PIXEL_RESOLUTION == 0: + if not subPixelResolution: points[:, 1] += left points[:, 0] += top