def update_for_sword(self): CmxRiffElement.update_for_sword(self) rifx = self.config.rifx self.cache_fields += [ (8, 2, 'Number of colors\n'), ] pos = 10 for _i in range(utils.word2py_int(self.chunk[8:10], rifx)): model = utils.byte2py_int(self.chunk[pos]) model_name = cmx_const.COLOR_MODEL_MAP.get(model, 'Unknown') self.cache_fields += [ (pos, 1, '%s color model' % model_name), ] palette = utils.byte2py_int(self.chunk[pos + 1]) pals = cmx_const.COLOR_PALETTES pal_name = pals[palette] if palette < len(pals) else 'Unknown' self.cache_fields += [ (pos + 1, 1, '%s palette' % pal_name), ] if model >= len(cmx_const.COLOR_BYTES): break clr_sz = cmx_const.COLOR_BYTES[model] self.cache_fields += [ (pos + 2, clr_sz, 'Color values\n'), ] pos += clr_sz + 2
def update_from_chunk(self): rifx = self.config.rifx colors = self.data['colors'] = [] pos = 10 for _i in range(utils.word2py_int(self.chunk[8:10], rifx)): model = utils.byte2py_int(self.chunk[pos]) palette = utils.byte2py_int(self.chunk[pos + 1]) if model < len(cmx_const.COLOR_BYTES): clr_sz = cmx_const.COLOR_BYTES[model] else: LOG.error('Invalide or unknown color model %s', model) break vals = tuple( utils.byte2py_int(val) for val in self.chunk[pos + 2:pos + 2 + clr_sz]) colors.append((model, palette, vals)) pos += clr_sz + 2
def get_markup(header, params): chunk = header + params element_class, element_id, params_sz = parse_header(header) is_padding = params_sz < len(params) cgm_cls_name = cgm_const.CGM_CLS.get(element_class, '') msg = 'Command Header\n' \ ' %d - element class\n' \ ' (%s)\n' \ ' 0x%04x - element id\n' \ ' %d - parameter list size (bytes)' \ % (element_class, cgm_cls_name, element_id, params_sz) msg += '\n' + '.' * 35 markup = [ (0, len(header), msg), ] hdsz = len(header) if params: if element_id == cgm_const.BEGIN_METAFILE: title_sz = utils.byte2py_int(params[0]) markup += [(hdsz, 1, 'text length'), (hdsz + 1, title_sz, 'file title')] elif element_id == cgm_const.METAFILE_VERSION: markup += [ (hdsz, 2, 'version'), ] elif element_id == cgm_const.METAFILE_DESCRIPTION: markup += [ (hdsz, 1, 'text length'), (hdsz + 1, params_sz - 1, 'description'), ] elif element_id == cgm_const.VDC_TYPE: markup += [ (hdsz, 2, 'VDC type (integer/real)'), ] elif element_id == cgm_const.APPLICATION_DATA: txt_sz = utils.byte2py_int(params[2]) markup += [ (hdsz, 2, 'identifier'), (hdsz + 2, 1, 'data length'), (hdsz + 3, txt_sz, 'application data'), ] elif element_id == cgm_const.INTEGER_PRECISION: markup += [ (hdsz, 2, 'integer precision\n ' '(8, 16, 24, 32 bit)'), ] elif element_id == cgm_const.REAL_PRECISION: markup += [ (hdsz, 2, 'real precision type'), (hdsz + 2, 2, 'integer part size'), (hdsz + 4, 2, 'fractional part size'), ] elif element_id == cgm_const.INDEX_PRECISION: markup += [ (hdsz, 2, 'index precision\n ' '(8, 16, 24, 32 bit)'), ] elif element_id == cgm_const.COLOUR_PRECISION: markup += [ (hdsz + params_sz - 2, 2, 'color precision type'), ] elif element_id == cgm_const.COLOUR_INDEX_PRECISION: markup += [ (hdsz + params_sz - 2, 2, 'color index precision type'), ] elif element_id == cgm_const.MAXIMUM_COLOUR_INDEX: markup += [ (hdsz, 2, 'max color index'), ] elif element_id == cgm_const.METAFILE_ELEMENT_LIST: markup += [ (hdsz, 2, 'list length'), (hdsz + 2, params_sz - 2, 'list of 2-byte elements'), ] elif element_id == cgm_const.COLOUR_VALUE_EXTENT: sz = params_sz / 2 markup += [ (hdsz, sz, 'bottom 3-member tuple'), (hdsz + sz, sz, 'top 3-member tuple'), ] elif element_id == cgm_const.FONT_LIST: pos = 0 fonts = [] while pos < params_sz: sz = utils.byte2py_int(params[pos]) pos += 1 fonts.append(params[pos:pos + sz].strip()) pos += sz markup += [ (hdsz, params_sz, 'font list pairs:\n' ' 1 byte - size of name\n' ' (sz) bytes - name string\n\nFonts:\n ' + '\n '.join(fonts) + '\n' + '.' * 35), ] elif element_id == cgm_const.BEGIN_PICTURE: markup += [ (hdsz, 1, 'text length'), (hdsz + 1, params_sz - 1, 'description'), ] elif element_id == cgm_const.VDC_EXTENT: sz = params_sz / 2 markup += [ (hdsz, sz, 'VDC lower left point'), (hdsz + sz, sz, 'VDC upper right point'), ] elif element_id == cgm_const.SCALING_MODE: markup += [ (hdsz, 2, 'scaling mode'), (hdsz + 2, 4, 'scaling metric'), ] elif element_id == cgm_const.COLOUR_SELECTION_MODE: markup += [ (hdsz, 2, 'color mode'), ] elif element_id == cgm_const.LINE_WIDTH_SPECIFICATION_MODE: markup += [ (hdsz, 2, 'line width specification mode'), ] elif element_id == cgm_const.MARKER_SIZE_SPECIFICATION_MODE: markup += [ (hdsz, 2, 'marker size specification mode'), ] elif element_id == cgm_const.EDGE_WIDTH_SPECIFICATION_MODE: markup += [ (hdsz, 2, 'edge width specification mode'), ] elif element_id == cgm_const.BACKGROUND_COLOUR: markup += [ (hdsz, params_sz, 'bg color'), ] elif element_id == cgm_const.VDC_INTEGER_PRECISION: markup += [ (hdsz, params_sz, 'vdc integer precision'), ] elif element_id == cgm_const.VDC_REAL_PRECISION: markup += [(hdsz, 2, ' precision type'), (hdsz + 2, params_sz - 2, ' 2 precision fields')] elif element_id == cgm_const.CLIP_RECTANGLE: markup += [ (hdsz, params_sz, 'clip rectangle (2 points)'), ] elif element_id == cgm_const.POLYLINE: markup += [ (hdsz, params_sz, 'polyline points'), ] elif element_id == cgm_const.DISJOINT_POLYLINE: markup += [ (hdsz, params_sz, 'disjoint polyline points'), ] elif element_id == cgm_const.TEXT: markup += [ (hdsz, params_sz, 'point + 2 byte flag + text'), ] elif element_id == cgm_const.POLYGON: markup += [ (hdsz, params_sz, 'points'), ] elif element_id == cgm_const.POLYGON_SET: markup += [ (hdsz, params_sz, 'point + 2 byte flag pairs'), ] elif element_id == cgm_const.RECTANGLE: sz = params_sz / 2 markup += [ (hdsz, sz, 'rect lower left point'), (hdsz + sz, sz, 'rect upper right point'), ] elif element_id == cgm_const.CIRCLE: sz = params_sz / 3 markup += [ (hdsz, sz, 'center x'), (hdsz + sz, sz, 'center y'), (hdsz + 2 * sz, sz, 'radius'), ] elif element_id == cgm_const.CIRCULAR_ARC_3_POINT: markup += [ (hdsz, params_sz, '3 points'), ] elif element_id == cgm_const.CIRCULAR_ARC_3_POINT_CLOSE: markup += [ (hdsz, params_sz, '3 points + close flag'), ] elif element_id == cgm_const.ELLIPSE: markup += [ (hdsz, params_sz, 'center + 2 cdp points'), ] elif element_id == cgm_const.LINE_TYPE: markup += [ (hdsz, params_sz, 'line type'), ] elif element_id == cgm_const.LINE_WIDTH: markup += [ (hdsz, params_sz, 'line width'), ] elif element_id == cgm_const.LINE_COLOUR: markup += [ (hdsz, params_sz, 'line color'), ] elif element_id == cgm_const.MARKER_COLOUR: markup += [ (hdsz, params_sz, 'marker color'), ] elif element_id == cgm_const.TEXT_FONT_INDEX: markup += [ (hdsz, params_sz, 'text font index'), ] elif element_id == cgm_const.CHARACTER_EXPANSION_FACTOR: markup += [ (hdsz, params_sz, 'character expansion'), ] elif element_id == cgm_const.CHARACTER_HEIGHT: markup += [ (hdsz, params_sz, 'character height'), ] elif element_id == cgm_const.CHARACTER_ORIENTATION: markup += [ (hdsz, params_sz, 'character orientation'), ] elif element_id == cgm_const.TEXT_ALIGNMENT: markup += [ (hdsz, 2, 'text alignment'), ] elif element_id == cgm_const.INTERIOR_STYLE: markup += [ (hdsz, params_sz, 'fill type'), ] elif element_id == cgm_const.FILL_COLOUR: markup += [ (hdsz, params_sz, 'fill color'), ] elif element_id == cgm_const.EDGE_TYPE: markup += [ (hdsz, params_sz, 'edge type'), ] elif element_id == cgm_const.EDGE_WIDTH: markup += [ (hdsz, params_sz, 'edge width'), ] elif element_id == cgm_const.EDGE_COLOUR: markup += [ (hdsz, params_sz, 'edge color'), ] elif element_id == cgm_const.EDGE_VISIBILITY: markup += [ (hdsz, params_sz, 'edge visibility'), ] elif element_id == cgm_const.COLOUR_TABLE: markup += [ (hdsz, params_sz, 'index + color values'), ] if is_padding: markup += [(len(chunk) - 1, 1, 'padding byte')] return markup
def read_str(self, chunk): if not chunk: return '', chunk sz = utils.byte2py_int(chunk[0]) title = chunk[1:1 + sz] return title, chunk[1 + sz:]
def readbyte(self): return utils.byte2py_int(self.fileptr.read(1))
def update_for_sword(self): rifx = self.config.rifx CmxInstruction.update_for_sword(self) flags = utils.byte2py_int(self.chunk[4]) self.cache_fields += [ (4, 1, 'Style flags'), ] pos = 5 if flags & cmx_const.INSTR_FILL_FLAG: fill = utils.word2py_int(self.chunk[pos:pos + 2], rifx) f = cmx_const.FILL_TYPE_MAP.get(fill, 'UNKNOWN') self.cache_fields += [ (pos, 2, 'Fill type: %s' % f), ] pos += 2 if fill == cmx_const.INSTR_FILL_EMPTY: pass elif fill == cmx_const.INSTR_FILL_UNIFORM: self.cache_fields += [ (pos, 2, 'Color ref.'), ] pos += 2 self.cache_fields += [ (pos, 2, 'Screen ref.'), ] pos += 2 elif fill == cmx_const.INSTR_FILL_FOUNTAIN: f = utils.word2py_int(self.chunk[pos:pos + 2], rifx) f = cmx_const.FILL_FOUNTAINS.get(f, 'unknown') self.cache_fields += [ (pos, 2, 'Fountain type: %s' % f), ] pos += 2 self.cache_fields += [ (pos, 2, 'Screen ref.'), ] pos += 2 self.cache_fields += [ (pos, 2, 'Padding'), ] pos += 2 self.cache_fields += [ (pos, 4, 'Angle'), ] pos += 4 self.cache_fields += [ (pos, 4, 'Offset (x,y) int16'), ] pos += 4 self.cache_fields += [ (pos, 2, 'Steps'), ] pos += 2 self.cache_fields += [ (pos, 2, 'Mode'), ] pos += 2 color_count = utils.word2py_int(self.chunk[pos:pos + 2], rifx) self.cache_fields += [ (pos, 2, 'Color count (%d)' % color_count), ] pos += 2 for _i in range(color_count): self.cache_fields += [ (pos, 2, 'Color ref.'), ] pos += 2 self.cache_fields += [ (pos, 2, 'Position'), ] pos += 2 else: pos, sz, txt = self.cache_fields[-1] txt += '\n UNSUPPORTED FILL TYPE!' self.cache_fields[-1] = (pos, sz, txt) return if flags & cmx_const.INSTR_STROKE_FLAG: self.cache_fields += [ (pos, 2, 'Outline ref.'), ] pos += 2 if flags >= cmx_const.INSTR_LENS_FLAG: pos, sz, txt = self.cache_fields[-1] sp = '\n ' txt += '%sUNSUPPORTED LENS, CANVAS %sOR CONTAINER!' % (sp, sp) self.cache_fields[-1] = (pos, sz, txt) return count = utils.word2py_int(self.chunk[pos:pos + 2], rifx) self.cache_fields += [ (pos, 2, 'Point count (%d)' % count), ] pos += 2 self.cache_fields += [ (pos, 4 * count, 'Points [(x,y),] int16'), ] pos += 4 * count self.cache_fields += [ (pos, count, 'Nodes [byte,]'), ] pos += count self.cache_fields += [ (pos, 8, 'Curve bbox'), ] pos += 8
def update_from_chunk(self): rifx = self.config.rifx self.data['tail'] = '' flags = self.data['style_flags'] = utils.byte2py_int(self.chunk[4]) pos = 5 if flags & cmx_const.INSTR_FILL_FLAG: fill = utils.word2py_int(self.chunk[pos:pos + 2], rifx) self.data['fill_type'] = fill pos += 2 # FILL if fill == cmx_const.INSTR_FILL_EMPTY: pass elif fill == cmx_const.INSTR_FILL_UNIFORM: # (color, screen) sig = '>hh' if rifx else '<hh' self.data['fill'] = struct.unpack(sig, self.chunk[pos:pos + 4]) pos += 4 elif fill == cmx_const.INSTR_FILL_FOUNTAIN: # (type, screen, padding, angle, x, y, steps, mode, clr_count) sig = '>hhhihhhh' if rifx else '<hhhihhhh' self.data['fill'] = struct.unpack(sig, self.chunk[pos:pos + 18]) pos += 18 # steps: [(color, pos)] sig = '>hh' if rifx else '<hh' steps = self.data['steps'] = [] for _ in range(self.data['fill'][-1]): steps.append(struct.unpack(sig, self.chunk[pos:pos + 4])) pos += 4 else: self.data['tail'] = self.chunk[pos:] return # OUTLINE if flags & cmx_const.INSTR_STROKE_FLAG: self.data['outline'] = utils.word2py_int(self.chunk[pos:pos + 2], rifx) pos += 2 if flags >= cmx_const.INSTR_LENS_FLAG: self.data['tail'] = self.chunk[pos:] return # POINTS & NODES # points: [(x,y),...] count = utils.word2py_int(self.chunk[pos:pos + 2], rifx) pos += 2 points = self.data['points'] = [] sig = '>hh' if rifx else '<hh' for _ in range(count): points.append(struct.unpack(sig, self.chunk[pos:pos + 4])) pos += 4 # nodes: (node,...) sig = count * 'B' self.data['nodes'] = struct.unpack(sig, self.chunk[pos:pos + count]) pos += count # BBOX sig = '>hhhh' if rifx else '<hhhh' self.data['bbox'] = struct.unpack(sig, self.chunk[pos:pos + 8]) pos += 8 if pos < len(self.chunk): self.data['tail'] = self.chunk[pos:]