emf 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (360) hide show
  1. checksums.yaml +4 -4
  2. data/README.adoc +224 -19
  3. data/exe/emf +12 -0
  4. data/lib/emf/backend.rb +60 -0
  5. data/lib/emf/binary/class_field_accessors.rb +49 -0
  6. data/lib/emf/binary/float32_le.rb +54 -0
  7. data/lib/emf/binary/types.rb +40 -6
  8. data/lib/emf/conformance/context.rb +36 -0
  9. data/lib/emf/conformance/diagnostic.rb +18 -0
  10. data/lib/emf/conformance/manifest/emf_bitmap_misc.yml +622 -0
  11. data/lib/emf/conformance/manifest/emf_control_buffers.yml +61 -0
  12. data/lib/emf/conformance/manifest/emf_core.yml +117 -0
  13. data/lib/emf/conformance/manifest/emf_corpus_rules.yml +21 -0
  14. data/lib/emf/conformance/manifest/emf_objects_geometry.yml +229 -0
  15. data/lib/emf/conformance/manifest/emf_plus.yml +357 -0
  16. data/lib/emf/conformance/manifest/emf_plus_core.yml +33 -0
  17. data/lib/emf/conformance/manifest/emf_state_path.yml +403 -0
  18. data/lib/emf/conformance/manifest/emf_text.yml +97 -0
  19. data/lib/emf/conformance/manifest/wmf.yml +874 -0
  20. data/lib/emf/conformance/manifest.rb +79 -0
  21. data/lib/emf/conformance/profile.rb +35 -0
  22. data/lib/emf/conformance/record_types.rb +24 -0
  23. data/lib/emf/conformance/registry.rb +76 -0
  24. data/lib/emf/conformance/report.rb +83 -0
  25. data/lib/emf/conformance/rule.rb +16 -0
  26. data/lib/emf/conformance/rules/emf_bitmap.rb +357 -0
  27. data/lib/emf/conformance/rules/emf_comment_escape.rb +309 -0
  28. data/lib/emf/conformance/rules/emf_control_buffers.rb +137 -0
  29. data/lib/emf/conformance/rules/emf_corpus_named.rb +83 -0
  30. data/lib/emf/conformance/rules/emf_framing.rb +94 -0
  31. data/lib/emf/conformance/rules/emf_geometry.rb +282 -0
  32. data/lib/emf/conformance/rules/emf_header.rb +114 -0
  33. data/lib/emf/conformance/rules/emf_objects.rb +291 -0
  34. data/lib/emf/conformance/rules/emf_parse_recovery.rb +97 -0
  35. data/lib/emf/conformance/rules/emf_path_clip.rb +165 -0
  36. data/lib/emf/conformance/rules/emf_plus.rb +75 -0
  37. data/lib/emf/conformance/rules/emf_plus_common.rb +58 -0
  38. data/lib/emf/conformance/rules/emf_plus_drawing.rb +78 -0
  39. data/lib/emf/conformance/rules/emf_plus_effects.rb +104 -0
  40. data/lib/emf/conformance/rules/emf_plus_fields.rb +169 -0
  41. data/lib/emf/conformance/rules/emf_plus_fields_b.rb +102 -0
  42. data/lib/emf/conformance/rules/emf_plus_framing.rb +172 -0
  43. data/lib/emf/conformance/rules/emf_plus_objects.rb +97 -0
  44. data/lib/emf/conformance/rules/emf_plus_payloads.rb +320 -0
  45. data/lib/emf/conformance/rules/emf_plus_properties.rb +96 -0
  46. data/lib/emf/conformance/rules/emf_plus_state.rb +77 -0
  47. data/lib/emf/conformance/rules/emf_state.rb +244 -0
  48. data/lib/emf/conformance/rules/emf_text.rb +221 -0
  49. data/lib/emf/conformance/rules/emf_transform.rb +85 -0
  50. data/lib/emf/conformance/rules/wmf_buffers.rb +259 -0
  51. data/lib/emf/conformance/rules/wmf_framing.rb +146 -0
  52. data/lib/emf/conformance/rules/wmf_layout_records.rb +112 -0
  53. data/lib/emf/conformance/rules/wmf_objects.rb +168 -0
  54. data/lib/emf/conformance/rules/wmf_records.rb +191 -0
  55. data/lib/emf/conformance/rules/wmf_rejections.rb +184 -0
  56. data/lib/emf/conformance/runner.rb +61 -0
  57. data/lib/emf/conformance/ternary_raster_operations.rb +52 -0
  58. data/lib/emf/conformance.rb +31 -0
  59. data/lib/emf/emf_plus/effects/blur.rb +24 -0
  60. data/lib/emf/emf_plus/effects/brightness_contrast.rb +22 -0
  61. data/lib/emf/emf_plus/effects/color_balance.rb +24 -0
  62. data/lib/emf/emf_plus/effects/color_curve.rb +24 -0
  63. data/lib/emf/emf_plus/effects/color_lookup_table.rb +26 -0
  64. data/lib/emf/emf_plus/effects/color_matrix.rb +23 -0
  65. data/lib/emf/emf_plus/effects/effect.rb +50 -0
  66. data/lib/emf/emf_plus/effects/hue_saturation_lightness.rb +24 -0
  67. data/lib/emf/emf_plus/effects/levels.rb +24 -0
  68. data/lib/emf/emf_plus/effects/opaque.rb +19 -0
  69. data/lib/emf/emf_plus/effects/red_eye_correction.rb +35 -0
  70. data/lib/emf/emf_plus/effects/sharpen.rb +24 -0
  71. data/lib/emf/emf_plus/effects/tint.rb +22 -0
  72. data/lib/emf/emf_plus/effects.rb +45 -0
  73. data/lib/emf/emf_plus/frame.rb +41 -0
  74. data/lib/emf/emf_plus/links/effect_link.rb +16 -0
  75. data/lib/emf/emf_plus/links/get_dc_span.rb +18 -0
  76. data/lib/emf/emf_plus/links/link_error.rb +15 -0
  77. data/lib/emf/emf_plus/links.rb +77 -0
  78. data/lib/emf/emf_plus/object_chain.rb +108 -0
  79. data/lib/emf/emf_plus/object_table.rb +182 -0
  80. data/lib/emf/emf_plus/objects/brush.rb +296 -0
  81. data/lib/emf/emf_plus/objects/custom_line_cap.rb +106 -0
  82. data/lib/emf/emf_plus/objects/font.rb +47 -0
  83. data/lib/emf/emf_plus/objects/image.rb +68 -0
  84. data/lib/emf/emf_plus/objects/image_attributes.rb +28 -0
  85. data/lib/emf/emf_plus/objects/opaque.rb +19 -0
  86. data/lib/emf/emf_plus/objects/parts.rb +103 -0
  87. data/lib/emf/emf_plus/objects/path.rb +21 -0
  88. data/lib/emf/emf_plus/objects/pen.rb +132 -0
  89. data/lib/emf/emf_plus/objects/region.rb +39 -0
  90. data/lib/emf/emf_plus/objects/string_format.rb +55 -0
  91. data/lib/emf/emf_plus/objects/typed.rb +50 -0
  92. data/lib/emf/emf_plus/objects.rb +46 -0
  93. data/lib/emf/emf_plus/parser.rb +64 -2
  94. data/lib/emf/emf_plus/records/base.rb +107 -0
  95. data/lib/emf/emf_plus/records/begin_container.rb +31 -0
  96. data/lib/emf/emf_plus/records/begin_container_no_params.rb +20 -0
  97. data/lib/emf/emf_plus/records/body.rb +16 -0
  98. data/lib/emf/emf_plus/records/clear.rb +22 -0
  99. data/lib/emf/emf_plus/records/clip_transform_flags.rb +26 -0
  100. data/lib/emf/emf_plus/records/comment.rb +21 -0
  101. data/lib/emf/emf_plus/records/draw_arc.rb +33 -0
  102. data/lib/emf/emf_plus/records/draw_beziers.rb +31 -0
  103. data/lib/emf/emf_plus/records/draw_closed_curve.rb +34 -0
  104. data/lib/emf/emf_plus/records/draw_curve.rb +38 -0
  105. data/lib/emf/emf_plus/records/draw_driver_string.rb +61 -0
  106. data/lib/emf/emf_plus/records/draw_ellipse.rb +28 -0
  107. data/lib/emf/emf_plus/records/draw_image.rb +42 -0
  108. data/lib/emf/emf_plus/records/draw_image_points.rb +62 -0
  109. data/lib/emf/emf_plus/records/draw_lines.rb +34 -0
  110. data/lib/emf/emf_plus/records/draw_path.rb +23 -0
  111. data/lib/emf/emf_plus/records/draw_pie.rb +33 -0
  112. data/lib/emf/emf_plus/records/draw_rects.rb +30 -0
  113. data/lib/emf/emf_plus/records/draw_string.rb +41 -0
  114. data/lib/emf/emf_plus/records/end_container.rb +20 -0
  115. data/lib/emf/emf_plus/records/end_of_file.rb +17 -0
  116. data/lib/emf/emf_plus/records/fill_brush.rb +21 -0
  117. data/lib/emf/emf_plus/records/fill_closed_curve.rb +38 -0
  118. data/lib/emf/emf_plus/records/fill_ellipse.rb +29 -0
  119. data/lib/emf/emf_plus/records/fill_path.rb +23 -0
  120. data/lib/emf/emf_plus/records/fill_pie.rb +34 -0
  121. data/lib/emf/emf_plus/records/fill_polygon.rb +32 -0
  122. data/lib/emf/emf_plus/records/fill_rects.rb +31 -0
  123. data/lib/emf/emf_plus/records/fill_region.rb +23 -0
  124. data/lib/emf/emf_plus/records/get_dc.rb +18 -0
  125. data/lib/emf/emf_plus/records/header.rb +35 -0
  126. data/lib/emf/emf_plus/records/multiply_world_transform.rb +24 -0
  127. data/lib/emf/emf_plus/records/object.rb +32 -0
  128. data/lib/emf/emf_plus/records/offset_clip.rb +24 -0
  129. data/lib/emf/emf_plus/records/primitives/argb.rb +20 -0
  130. data/lib/emf/emf_plus/records/primitives/bitmap.rb +32 -0
  131. data/lib/emf/emf_plus/records/primitives/bitmap_data.rb +21 -0
  132. data/lib/emf/emf_plus/records/primitives/blend_colors.rb +22 -0
  133. data/lib/emf/emf_plus/records/primitives/blend_factors.rb +21 -0
  134. data/lib/emf/emf_plus/records/primitives/bounded_array.rb +38 -0
  135. data/lib/emf/emf_plus/records/primitives/byte_reader.rb +25 -0
  136. data/lib/emf/emf_plus/records/primitives/character_range.rb +20 -0
  137. data/lib/emf/emf_plus/records/primitives/compressed_image.rb +17 -0
  138. data/lib/emf/emf_plus/records/primitives/focus_scale_data.rb +20 -0
  139. data/lib/emf/emf_plus/records/primitives/graphics_version.rb +21 -0
  140. data/lib/emf/emf_plus/records/primitives/language_identifier.rb +22 -0
  141. data/lib/emf/emf_plus/records/primitives/metafile.rb +19 -0
  142. data/lib/emf/emf_plus/records/primitives/palette.rb +21 -0
  143. data/lib/emf/emf_plus/records/primitives/path.rb +89 -0
  144. data/lib/emf/emf_plus/records/primitives/path_point_type.rb +21 -0
  145. data/lib/emf/emf_plus/records/primitives/path_point_type_rle.rb +23 -0
  146. data/lib/emf/emf_plus/records/primitives/point.rb +18 -0
  147. data/lib/emf/emf_plus/records/primitives/point_array.rb +42 -0
  148. data/lib/emf/emf_plus/records/primitives/point_f.rb +19 -0
  149. data/lib/emf/emf_plus/records/primitives/point_r.rb +19 -0
  150. data/lib/emf/emf_plus/records/primitives/rect.rb +20 -0
  151. data/lib/emf/emf_plus/records/primitives/rect_array.rb +24 -0
  152. data/lib/emf/emf_plus/records/primitives/rect_f.rb +21 -0
  153. data/lib/emf/emf_plus/records/primitives/region_node.rb +68 -0
  154. data/lib/emf/emf_plus/records/primitives/region_node_child_nodes.rb +22 -0
  155. data/lib/emf/emf_plus/records/primitives/region_node_path.rb +37 -0
  156. data/lib/emf/emf_plus/records/primitives/relative_coordinate.rb +32 -0
  157. data/lib/emf/emf_plus/records/primitives/string_format_data.rb +23 -0
  158. data/lib/emf/emf_plus/records/primitives/transform_matrix.rb +23 -0
  159. data/lib/emf/emf_plus/records/primitives.rb +41 -0
  160. data/lib/emf/emf_plus/records/reset_clip.rb +17 -0
  161. data/lib/emf/emf_plus/records/reset_world_transform.rb +17 -0
  162. data/lib/emf/emf_plus/records/restore.rb +20 -0
  163. data/lib/emf/emf_plus/records/rotate_world_transform.rb +24 -0
  164. data/lib/emf/emf_plus/records/save.rb +20 -0
  165. data/lib/emf/emf_plus/records/scale_world_transform.rb +26 -0
  166. data/lib/emf/emf_plus/records/serializable_object.rb +32 -0
  167. data/lib/emf/emf_plus/records/set_anti_alias_mode.rb +25 -0
  168. data/lib/emf/emf_plus/records/set_clip_path.rb +20 -0
  169. data/lib/emf/emf_plus/records/set_clip_rect.rb +24 -0
  170. data/lib/emf/emf_plus/records/set_clip_region.rb +20 -0
  171. data/lib/emf/emf_plus/records/set_compositing_mode.rb +21 -0
  172. data/lib/emf/emf_plus/records/set_compositing_quality.rb +21 -0
  173. data/lib/emf/emf_plus/records/set_interpolation_mode.rb +21 -0
  174. data/lib/emf/emf_plus/records/set_page_transform.rb +25 -0
  175. data/lib/emf/emf_plus/records/set_pixel_offset_mode.rb +21 -0
  176. data/lib/emf/emf_plus/records/set_rendering_origin.rb +22 -0
  177. data/lib/emf/emf_plus/records/set_text_contrast.rb +24 -0
  178. data/lib/emf/emf_plus/records/set_text_rendering_hint.rb +21 -0
  179. data/lib/emf/emf_plus/records/set_ts_clip.rb +40 -0
  180. data/lib/emf/emf_plus/records/set_ts_graphics.rb +88 -0
  181. data/lib/emf/emf_plus/records/set_world_transform.rb +22 -0
  182. data/lib/emf/emf_plus/records/shape_flags.rb +23 -0
  183. data/lib/emf/emf_plus/records/translate_world_transform.rb +26 -0
  184. data/lib/emf/emf_plus/records/unknown.rb +20 -0
  185. data/lib/emf/emf_plus/records.rb +107 -0
  186. data/lib/emf/emf_plus/serializer.rb +9 -2
  187. data/lib/emf/emf_plus/stream/conformance.rb +68 -0
  188. data/lib/emf/emf_plus/stream/editor.rb +21 -0
  189. data/lib/emf/emf_plus/stream/emf_gap.rb +20 -0
  190. data/lib/emf/emf_plus/stream/link_index.rb +30 -0
  191. data/lib/emf/emf_plus/stream/rebuild.rb +47 -0
  192. data/lib/emf/emf_plus/stream/record_handle.rb +26 -0
  193. data/lib/emf/emf_plus/stream/segment.rb +70 -0
  194. data/lib/emf/emf_plus/stream.rb +153 -0
  195. data/lib/emf/emf_plus.rb +9 -0
  196. data/lib/emf/emr/binary/dib_header.rb +142 -0
  197. data/lib/emf/emr/binary/ext_text_out_fields.rb +43 -0
  198. data/lib/emf/emr/binary/extended_pen_buffers.rb +23 -0
  199. data/lib/emf/emr/binary/fast_fill.rb +1164 -0
  200. data/lib/emf/emr/binary/font.rb +159 -0
  201. data/lib/emf/emr/binary/lazy_utf16_array.rb +82 -0
  202. data/lib/emf/emr/binary/pack_plan.rb +144 -0
  203. data/lib/emf/emr/binary/pack_plan_check.rb +75 -0
  204. data/lib/emf/emr/binary/pack_plan_exact.rb +130 -0
  205. data/lib/emf/emr/binary/pack_plan_generate.rb +116 -0
  206. data/lib/emf/emr/binary/pack_plan_values.rb +92 -0
  207. data/lib/emf/emr/binary/palette_body.rb +19 -0
  208. data/lib/emf/emr/binary/palette_entry.rb +18 -0
  209. data/lib/emf/emr/binary/record.rb +33 -0
  210. data/lib/emf/emr/binary/records/alpha_blend.rb +43 -0
  211. data/lib/emf/emr/binary/records/angle_arc.rb +2 -2
  212. data/lib/emf/emr/binary/records/bit_blt.rb +14 -0
  213. data/lib/emf/emr/binary/records/color_correct_palette.rb +55 -1
  214. data/lib/emf/emr/binary/records/colormatch_to_target_w.rb +76 -1
  215. data/lib/emf/emr/binary/records/create_colorspace.rb +67 -1
  216. data/lib/emf/emr/binary/records/create_colorspace_w.rb +90 -1
  217. data/lib/emf/emr/binary/records/create_dib_pattern_brush_pt.rb +14 -0
  218. data/lib/emf/emr/binary/records/create_font_indirect_w.rb +6 -2
  219. data/lib/emf/emr/binary/records/create_mono_brush.rb +14 -0
  220. data/lib/emf/emr/binary/records/create_palette.rb +19 -1
  221. data/lib/emf/emr/binary/records/delete_colorspace.rb +22 -1
  222. data/lib/emf/emr/binary/records/draw_escape.rb +45 -1
  223. data/lib/emf/emr/binary/records/ellipse.rb +1 -1
  224. data/lib/emf/emr/binary/records/eof.rb +9 -0
  225. data/lib/emf/emr/binary/records/ext_create_pen.rb +80 -1
  226. data/lib/emf/emr/binary/records/ext_escape.rb +45 -1
  227. data/lib/emf/emr/binary/records/ext_flood_fill.rb +9 -2
  228. data/lib/emf/emr/binary/records/ext_select_clip_rgn.rb +9 -1
  229. data/lib/emf/emr/binary/records/ext_text_out_a.rb +16 -3
  230. data/lib/emf/emr/binary/records/ext_text_out_w.rb +14 -3
  231. data/lib/emf/emr/binary/records/fill_rgn.rb +11 -2
  232. data/lib/emf/emr/binary/records/force_ufi_mapping.rb +38 -1
  233. data/lib/emf/emr/binary/records/frame_rgn.rb +12 -2
  234. data/lib/emf/emr/binary/records/gls_bounded_record.rb +61 -1
  235. data/lib/emf/emr/binary/records/gls_record.rb +42 -1
  236. data/lib/emf/emr/binary/records/gradient_fill.rb +7 -0
  237. data/lib/emf/emr/binary/records/invert_rgn.rb +11 -3
  238. data/lib/emf/emr/binary/records/mask_blt.rb +66 -0
  239. data/lib/emf/emr/binary/records/named_escape.rb +78 -1
  240. data/lib/emf/emr/binary/records/paint_rgn.rb +11 -3
  241. data/lib/emf/emr/binary/records/pixel_format.rb +76 -1
  242. data/lib/emf/emr/binary/records/plg_blt.rb +66 -0
  243. data/lib/emf/emr/binary/records/poly_textout_a.rb +128 -1
  244. data/lib/emf/emr/binary/records/poly_textout_w.rb +128 -1
  245. data/lib/emf/emr/binary/records/raw.rb +3 -0
  246. data/lib/emf/emr/binary/records/realize_palette.rb +1 -0
  247. data/lib/emf/emr/binary/records/rectangle.rb +1 -1
  248. data/lib/emf/emr/binary/records/resize_palette.rb +16 -2
  249. data/lib/emf/emr/binary/records/round_rect.rb +2 -2
  250. data/lib/emf/emr/binary/records/select_palette.rb +1 -0
  251. data/lib/emf/emr/binary/records/set_color_adjustment.rb +136 -0
  252. data/lib/emf/emr/binary/records/set_colorspace.rb +22 -1
  253. data/lib/emf/emr/binary/records/set_dibits_to_device.rb +43 -0
  254. data/lib/emf/emr/binary/records/set_icm_profile_a.rb +71 -1
  255. data/lib/emf/emr/binary/records/set_icm_profile_w.rb +71 -1
  256. data/lib/emf/emr/binary/records/set_linked_ufis.rb +49 -1
  257. data/lib/emf/emr/binary/records/set_miter_limit.rb +1 -1
  258. data/lib/emf/emr/binary/records/set_palette_entries.rb +20 -2
  259. data/lib/emf/emr/binary/records/set_text_justification.rb +8 -2
  260. data/lib/emf/emr/binary/records/small_text_out.rb +55 -4
  261. data/lib/emf/emr/binary/records/stretch_blt.rb +14 -0
  262. data/lib/emf/emr/binary/records/stretch_dibits.rb +14 -0
  263. data/lib/emf/emr/binary/records/transparent_blt.rb +43 -0
  264. data/lib/emf/emr/binary/records.rb +4 -2
  265. data/lib/emf/emr/binary/region_data.rb +33 -0
  266. data/lib/emf/emr/binary/state_record_body.rb +33 -0
  267. data/lib/emf/emr/binary/thin_shell.rb +226 -0
  268. data/lib/emf/emr/binary/value_view/layout.rb +101 -0
  269. data/lib/emf/emr/binary/value_view/reader_source.rb +88 -0
  270. data/lib/emf/emr/binary/value_view.rb +173 -0
  271. data/lib/emf/emr/binary/variable_buffers.rb +87 -0
  272. data/lib/emf/emr/binary.rb +4 -0
  273. data/lib/emf/emr/filled_record.rb +77 -0
  274. data/lib/emf/emr/parser.rb +239 -50
  275. data/lib/emf/emr/serializer.rb +4 -5
  276. data/lib/emf/emr.rb +1 -0
  277. data/lib/emf/error.rb +24 -1
  278. data/lib/emf/model/diagnostic.rb +41 -0
  279. data/lib/emf/model/emr/header.rb +40 -1
  280. data/lib/emf/model/emr/records.rb +142 -6
  281. data/lib/emf/model/emr/wire_values.rb +43 -0
  282. data/lib/emf/model/emr.rb +1 -0
  283. data/lib/emf/model/geometry/color.rb +19 -1
  284. data/lib/emf/model/metafile.rb +22 -2
  285. data/lib/emf/model/wmf/bitmap_records.rb +155 -0
  286. data/lib/emf/model/wmf/brush_records.rb +45 -0
  287. data/lib/emf/model/wmf/dc_escape_records.rb +67 -0
  288. data/lib/emf/model/wmf/font_record.rb +40 -0
  289. data/lib/emf/model/wmf/geometry_records.rb +107 -0
  290. data/lib/emf/model/wmf/header.rb +36 -0
  291. data/lib/emf/model/wmf/object_records.rb +71 -0
  292. data/lib/emf/model/wmf/palette_records.rb +68 -0
  293. data/lib/emf/model/wmf/records.rb +247 -0
  294. data/lib/emf/model/wmf/region_records.rb +112 -0
  295. data/lib/emf/model/wmf/state_records.rb +188 -0
  296. data/lib/emf/model/wmf/text_records.rb +36 -0
  297. data/lib/emf/model/wmf.rb +11 -0
  298. data/lib/emf/model.rb +2 -0
  299. data/lib/emf/native/bitmap_fields.rb +58 -0
  300. data/lib/emf/native/diagnostic_contract.rb +39 -0
  301. data/lib/emf/native/diagnostics.rb +81 -0
  302. data/lib/emf/native/emf_plus_loader.rb +35 -0
  303. data/lib/emf/native/emf_plus_snapshot.rb +96 -0
  304. data/lib/emf/native/emf_plus_source.rb +20 -0
  305. data/lib/emf/native/emf_plus_stream.rb +150 -0
  306. data/lib/emf/native/fields.rb +369 -0
  307. data/lib/emf/native/font_fields.rb +87 -0
  308. data/lib/emf/native/gradient_fields.rb +23 -0
  309. data/lib/emf/native/header.rb +35 -0
  310. data/lib/emf/native/header_errors.rb +30 -0
  311. data/lib/emf/native/hydrator.rb +151 -0
  312. data/lib/emf/native/lazy_wire.rb +100 -0
  313. data/lib/emf/native/legacy_state_fields.rb +22 -0
  314. data/lib/emf/native/library_path.rb +68 -0
  315. data/lib/emf/native/loader.rb +120 -0
  316. data/lib/emf/native/palette_fields.rb +45 -0
  317. data/lib/emf/native/poly_text_fields.rb +116 -0
  318. data/lib/emf/native/resource_failure.rb +28 -0
  319. data/lib/emf/native/small_text_fields.rb +27 -0
  320. data/lib/emf/native/snapshot.rb +102 -0
  321. data/lib/emf/native/wmf_bitmap_fields.rb +58 -0
  322. data/lib/emf/native/wmf_brush_fields.rb +62 -0
  323. data/lib/emf/native/wmf_fields.rb +117 -0
  324. data/lib/emf/native/wmf_hydrator.rb +143 -0
  325. data/lib/emf/native/wmf_loading.rb +49 -0
  326. data/lib/emf/native/wmf_palette_fields.rb +60 -0
  327. data/lib/emf/native/wmf_region_fields.rb +92 -0
  328. data/lib/emf/native/wmf_rejection.rb +84 -0
  329. data/lib/emf/native/wmf_remaining_fields.rb +70 -0
  330. data/lib/emf/native/wmf_snapshot.rb +51 -0
  331. data/lib/emf/native/wmf_text_fields.rb +56 -0
  332. data/lib/emf/native.rb +61 -0
  333. data/lib/emf/parse_evidence.rb +57 -0
  334. data/lib/emf/resource_budget/bitmap.rb +66 -0
  335. data/lib/emf/resource_budget/gradient.rb +30 -0
  336. data/lib/emf/resource_budget/poly_text.rb +85 -0
  337. data/lib/emf/resource_budget.rb +382 -0
  338. data/lib/emf/resource_limits/emf_records.rb +130 -0
  339. data/lib/emf/resource_limits.rb +58 -0
  340. data/lib/emf/version.rb +1 -1
  341. data/lib/emf/visitors/dump.rb +4 -0
  342. data/lib/emf/visitors/stats.rb +6 -5
  343. data/lib/emf/wmf/binary.rb +150 -1
  344. data/lib/emf/wmf/bitmap_codec.rb +118 -0
  345. data/lib/emf/wmf/brush_codec.rb +102 -0
  346. data/lib/emf/wmf/dc_escape_codec.rb +75 -0
  347. data/lib/emf/wmf/dib.rb +187 -0
  348. data/lib/emf/wmf/embedded_emf.rb +137 -0
  349. data/lib/emf/wmf/escape_views.rb +89 -0
  350. data/lib/emf/wmf/evidence.rb +255 -0
  351. data/lib/emf/wmf/geometry_codec.rb +49 -0
  352. data/lib/emf/wmf/palette_codec.rb +85 -0
  353. data/lib/emf/wmf/parser.rb +147 -2
  354. data/lib/emf/wmf/recovery.rb +95 -0
  355. data/lib/emf/wmf/region_codec.rb +151 -0
  356. data/lib/emf/wmf/serializer.rb +164 -2
  357. data/lib/emf/wmf/text_codec.rb +123 -0
  358. data/lib/emf/wmf.rb +7 -0
  359. data/lib/emf.rb +13 -9
  360. metadata +287 -10
@@ -7,9 +7,46 @@ module Emf
7
7
  module Emr
8
8
  module Binary
9
9
  module Records
10
- # Stub: preserves full body bytes. Full layout lands with TODO 10.
10
+ # Universal font identifiers retain their original byte representation.
11
11
  class ForceUfiMapping < Emf::Emr::Binary::Record
12
12
  rest :body
13
+
14
+ [[:ufi_checksum, 0], [:ufi_index, 4]].each do |name, offset|
15
+ define_method(name) { ufi_body.byteslice(offset, 4).unpack1("V") }
16
+ define_method("#{name}=") do |value|
17
+ ufi_body
18
+ raise ArgumentError, "UFI value must be an Integer" unless value.is_a?(Integer)
19
+ raise RangeError, "UFI value must fit an unsigned 32-bit integer" unless (0..0xFFFFFFFF).cover?(value)
20
+
21
+ replace_ufi_bytes(offset, 4, [value].pack("V"))
22
+ end
23
+ end
24
+
25
+ def ufi_bytes
26
+ ufi_body.byteslice(0, 8).b
27
+ end
28
+
29
+ def ufi_bytes=(value)
30
+ replace_ufi_bytes(0, 8, value)
31
+ end
32
+
33
+ private
34
+
35
+ def ufi_body
36
+ bytes = body.to_s
37
+ raise ArgumentError, "truncated universal font identifier" if bytes.bytesize < 8
38
+
39
+ bytes
40
+ end
41
+
42
+ def replace_ufi_bytes(offset, length, value)
43
+ bytes = ufi_body
44
+ raise ArgumentError, "UFI value must be a String of #{length} bytes" unless value.is_a?(String) && value.bytesize == length
45
+
46
+ replacement = bytes.b
47
+ replacement[offset, length] = value.b
48
+ self.body = replacement
49
+ end
13
50
  end
14
51
  end
15
52
  end
@@ -1,14 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "bindata"
4
- require "emf/emr/binary/record"
4
+ require "emf/emr/binary/variable_buffers"
5
+ require "emf/emr/binary/with_bounds"
6
+ require "emf/emr/binary/region_data"
5
7
 
6
8
  module Emf
7
9
  module Emr
8
10
  module Binary
9
11
  module Records
10
- class FrameRgn < Emf::Emr::Binary::Record
12
+ class FrameRgn < Emf::Emr::Binary::WithBounds
13
+ include Emf::Emr::Binary::VariableBuffers
14
+
15
+ fixed_layout 40
16
+ variable_buffer :region_bytes, offset: 40, length: :cb_rgn_data
17
+
18
+ uint32 :cb_rgn_data
11
19
  uint32 :ih_brush
20
+ size_l :szl_stroke
21
+ region_data :rgn_data, byte_length: :cb_rgn_data
12
22
  rest :body
13
23
  end
14
24
  end
@@ -7,9 +7,69 @@ module Emf
7
7
  module Emr
8
8
  module Binary
9
9
  module Records
10
- # Stub: preserves full body bytes. Full layout lands with TODO 10.
10
+ # EMR_GLSBOUNDEDRECORD (MS-EMF 2.3.5.23).
11
11
  class GlsBoundedRecord < Emf::Emr::Binary::Record
12
12
  rest :body
13
+
14
+ def bounds
15
+ gls_body.byteslice(0, 16).b
16
+ end
17
+
18
+ def bounds=(value)
19
+ write_gls_bytes(0, 16, value)
20
+ end
21
+
22
+ def cb_data
23
+ gls_body.byteslice(16, 4).unpack1("V")
24
+ end
25
+
26
+ def data_bytes
27
+ read_gls_data
28
+ end
29
+
30
+ def data_bytes=(value)
31
+ write_gls_data(value)
32
+ end
33
+
34
+ private
35
+
36
+ def gls_body
37
+ bytes = body.to_s
38
+ raise ArgumentError, "truncated bounded GLS record prefix" if bytes.bytesize < 20
39
+
40
+ bytes
41
+ end
42
+
43
+ def read_gls_data
44
+ bytes = gls_body
45
+ length = bytes.byteslice(16, 4).unpack1("V")
46
+ raise ArgumentError, "truncated bounded GLS record data" if 20 + length > bytes.bytesize
47
+
48
+ bytes.byteslice(20, length).b
49
+ end
50
+
51
+ def write_gls_data(value)
52
+ read_gls_data
53
+ length = cb_data
54
+ unless value.is_a?(String) && value.bytesize == length
55
+ raise ArgumentError, "bounded GLS data must be a String of #{length} bytes"
56
+ end
57
+
58
+ bytes = body.to_s.b
59
+ bytes[20, length] = value.b
60
+ self.body = bytes
61
+ end
62
+
63
+ def write_gls_bytes(offset, length, value)
64
+ gls_body
65
+ unless value.is_a?(String) && value.bytesize == length
66
+ raise ArgumentError, "bounded GLS value must be a String of #{length} bytes"
67
+ end
68
+
69
+ bytes = body.to_s.b
70
+ bytes[offset, length] = value.b
71
+ self.body = bytes
72
+ end
13
73
  end
14
74
  end
15
75
  end
@@ -7,9 +7,50 @@ module Emf
7
7
  module Emr
8
8
  module Binary
9
9
  module Records
10
- # Stub: preserves full body bytes. Full layout lands with TODO 10.
10
+ # EMR_GLSRECORD (MS-EMF 2.3.5.24).
11
11
  class GlsRecord < Emf::Emr::Binary::Record
12
12
  rest :body
13
+
14
+ def cb_data
15
+ gls_body(4).byteslice(0, 4).unpack1("V")
16
+ end
17
+
18
+ def data_bytes
19
+ read_gls_data(4)
20
+ end
21
+
22
+ def data_bytes=(value)
23
+ write_gls_data(4, value)
24
+ end
25
+
26
+ private
27
+
28
+ def gls_body(prefix_length)
29
+ bytes = body.to_s
30
+ raise ArgumentError, "truncated GLS record prefix" if bytes.bytesize < prefix_length
31
+
32
+ bytes
33
+ end
34
+
35
+ def read_gls_data(prefix_length)
36
+ bytes = gls_body(prefix_length)
37
+ length = bytes.byteslice(0, 4).unpack1("V")
38
+ raise ArgumentError, "truncated GLS record data" if prefix_length + length > bytes.bytesize
39
+
40
+ bytes.byteslice(prefix_length, length).b
41
+ end
42
+
43
+ def write_gls_data(prefix_length, value)
44
+ read_gls_data(prefix_length)
45
+ length = cb_data
46
+ unless value.is_a?(String) && value.bytesize == length
47
+ raise ArgumentError, "GLS record data must be a String of #{length} bytes"
48
+ end
49
+
50
+ bytes = body.to_s.b
51
+ bytes[prefix_length, length] = value.b
52
+ self.body = bytes
53
+ end
13
54
  end
14
55
  end
15
56
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "bindata"
4
+ require "emf/emr/binary/variable_buffers"
4
5
  require "emf/emr/binary/with_bounds"
5
6
 
6
7
  module Emf
@@ -8,6 +9,12 @@ module Emf
8
9
  module Binary
9
10
  module Records
10
11
  class GradientFill < Emf::Emr::Binary::WithBounds
12
+ include Emf::Emr::Binary::VariableBuffers
13
+
14
+ fixed_layout 36
15
+ variable_buffer :vertex_bytes, offset: 36, length: -> { n_ver * 16 }
16
+ variable_buffer :mesh_bytes, offset: -> { 36 + (n_ver * 16) }, length: -> { n_tri * (ul_mode == 2 ? 12 : 8) }
17
+
11
18
  uint32 :n_ver
12
19
  uint32 :n_tri
13
20
  uint32 :ul_mode
@@ -1,14 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "bindata"
4
- require "emf/emr/binary/record"
4
+ require "emf/emr/binary/variable_buffers"
5
+ require "emf/emr/binary/with_bounds"
6
+ require "emf/emr/binary/region_data"
5
7
 
6
8
  module Emf
7
9
  module Emr
8
10
  module Binary
9
11
  module Records
10
- class InvertRgn < Emf::Emr::Binary::Record
11
- uint32 :ih_brush
12
+ class InvertRgn < Emf::Emr::Binary::WithBounds
13
+ include Emf::Emr::Binary::VariableBuffers
14
+
15
+ fixed_layout 28
16
+ variable_buffer :region_bytes, offset: 28, length: :cb_rgn_data
17
+
18
+ uint32 :cb_rgn_data
19
+ region_data :rgn_data, byte_length: :cb_rgn_data
12
20
  rest :body
13
21
  end
14
22
  end
@@ -1,15 +1,81 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "bindata"
4
+ require "emf/emr/binary/variable_buffers"
4
5
  require "emf/emr/binary/with_bounds"
6
+ require "emf/emr/binary/dib_header"
5
7
 
6
8
  module Emf
7
9
  module Emr
8
10
  module Binary
9
11
  module Records
10
12
  # Stub: leading fields per MS-EMF, body captures remaining bytes.
13
+ # The fixed part is 128 bytes including the EMR header; the bitmap
14
+ # pointers are read from body without declaring fields.
11
15
  class MaskBlt < Emf::Emr::Binary::WithBounds
16
+ include Emf::Emr::Binary::VariableBuffers
17
+
18
+ fixed_layout 128
19
+ variable_buffer :bmi_bytes, offset: :off_bmi_src, length: :cb_bmi_src
20
+ variable_buffer :bits_bytes, offset: :off_bits_src, length: :cb_bits_src
21
+ variable_buffer :mask_bmi_bytes, offset: :off_bmi_mask, length: :cb_bmi_mask
22
+ variable_buffer :mask_bits_bytes, offset: :off_bits_mask, length: :cb_bits_mask
23
+
12
24
  rest :body
25
+
26
+ # Read-only accessors computed from body on each call; body starts at
27
+ # record offset 24, so a record offset maps to (offset - 24) in body.
28
+ def off_bmi_src
29
+ pointers(60)[0]
30
+ end
31
+
32
+ def cb_bmi_src
33
+ pointers(60)[1]
34
+ end
35
+
36
+ def off_bits_src
37
+ pointers(60)[2]
38
+ end
39
+
40
+ def cb_bits_src
41
+ pointers(60)[3]
42
+ end
43
+
44
+ def off_bmi_mask
45
+ pointers(88)[0]
46
+ end
47
+
48
+ def cb_bmi_mask
49
+ pointers(88)[1]
50
+ end
51
+
52
+ def off_bits_mask
53
+ pointers(88)[2]
54
+ end
55
+
56
+ def cb_bits_mask
57
+ pointers(88)[3]
58
+ end
59
+
60
+ def dib_header_view
61
+ DibHeader.view(off_bmi_src, cb_bmi_src, 128, after_fixed,
62
+ bits_offset: off_bits_src, bits_size: cb_bits_src)
63
+ end
64
+
65
+ def mask_dib_header_view
66
+ DibHeader.view(off_bmi_mask, cb_bmi_mask, 128, after_fixed,
67
+ bits_offset: off_bits_mask, bits_size: cb_bits_mask)
68
+ end
69
+
70
+ private
71
+
72
+ def after_fixed
73
+ body.to_s.byteslice(104..).to_s
74
+ end
75
+
76
+ def pointers(offset)
77
+ body.to_s.byteslice(offset, 16).to_s.unpack("V4").map(&:to_i)
78
+ end
13
79
  end
14
80
  end
15
81
  end
@@ -7,9 +7,86 @@ module Emf
7
7
  module Emr
8
8
  module Binary
9
9
  module Records
10
- # Stub: preserves full body bytes. Full layout lands with TODO 10.
10
+ # Body-backed byte spans retain the driver's raw name, data and padding.
11
11
  class NamedEscape < Emf::Emr::Binary::Record
12
12
  rest :body
13
+
14
+ def i_escape
15
+ named_escape_body.byteslice(0, 4).unpack1("V")
16
+ end
17
+
18
+ def i_escape=(value)
19
+ bytes = named_escape_body
20
+ raise ArgumentError, "i_escape must be an Integer" unless value.is_a?(Integer)
21
+ raise RangeError, "i_escape must fit in an unsigned 32-bit field" unless value.between?(0, 0xFFFFFFFF)
22
+
23
+ bytes[0, 4] = [value].pack("V")
24
+ self.body = bytes
25
+ end
26
+
27
+ def cj_driver
28
+ named_escape_body.byteslice(4, 4).unpack1("V")
29
+ end
30
+
31
+ def cj_in
32
+ named_escape_body.byteslice(8, 4).unpack1("V")
33
+ end
34
+
35
+ def driver_name_bytes
36
+ bytes = named_escape_body
37
+ length = bytes.byteslice(4, 4).unpack1("V")
38
+ validate_span!(bytes, 12, length, "driver name")
39
+ bytes.byteslice(12, length).b
40
+ end
41
+
42
+ def driver_name_bytes=(value)
43
+ bytes = named_escape_body
44
+ length = bytes.byteslice(4, 4).unpack1("V")
45
+ validate_span!(bytes, 12, length, "driver name")
46
+ validate_bytes!(value, length, "driver name")
47
+ bytes[12, length] = value.b
48
+ self.body = bytes
49
+ end
50
+
51
+ def data_bytes
52
+ bytes = named_escape_body
53
+ driver_length = bytes.byteslice(4, 4).unpack1("V")
54
+ data_length = bytes.byteslice(8, 4).unpack1("V")
55
+ data_offset = 12 + driver_length
56
+ validate_span!(bytes, 12, driver_length, "driver name")
57
+ validate_span!(bytes, data_offset, data_length, "data")
58
+ bytes.byteslice(data_offset, data_length).b
59
+ end
60
+
61
+ def data_bytes=(value)
62
+ bytes = named_escape_body
63
+ driver_length = bytes.byteslice(4, 4).unpack1("V")
64
+ data_length = bytes.byteslice(8, 4).unpack1("V")
65
+ data_offset = 12 + driver_length
66
+ validate_span!(bytes, 12, driver_length, "driver name")
67
+ validate_span!(bytes, data_offset, data_length, "data")
68
+ validate_bytes!(value, data_length, "data")
69
+ bytes[data_offset, data_length] = value.b
70
+ self.body = bytes
71
+ end
72
+
73
+ private
74
+
75
+ def named_escape_body
76
+ bytes = body.to_s.b
77
+ raise ArgumentError, "truncated named escape prefix" if bytes.bytesize < 12
78
+
79
+ bytes
80
+ end
81
+
82
+ def validate_span!(bytes, offset, length, name)
83
+ raise ArgumentError, "truncated named escape #{name}" if length > bytes.bytesize - offset
84
+ end
85
+
86
+ def validate_bytes!(value, length, name)
87
+ valid = value.is_a?(String) && value.bytesize == length
88
+ raise ArgumentError, "#{name} must be a String of #{length} bytes" unless valid
89
+ end
13
90
  end
14
91
  end
15
92
  end
@@ -1,14 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "bindata"
4
- require "emf/emr/binary/record"
4
+ require "emf/emr/binary/variable_buffers"
5
+ require "emf/emr/binary/with_bounds"
6
+ require "emf/emr/binary/region_data"
5
7
 
6
8
  module Emf
7
9
  module Emr
8
10
  module Binary
9
11
  module Records
10
- class PaintRgn < Emf::Emr::Binary::Record
11
- uint32 :ih_brush
12
+ class PaintRgn < Emf::Emr::Binary::WithBounds
13
+ include Emf::Emr::Binary::VariableBuffers
14
+
15
+ fixed_layout 28
16
+ variable_buffer :region_bytes, offset: 28, length: :cb_rgn_data
17
+
18
+ uint32 :cb_rgn_data
19
+ region_data :rgn_data, byte_length: :cb_rgn_data
12
20
  rest :body
13
21
  end
14
22
  end
@@ -7,9 +7,84 @@ module Emf
7
7
  module Emr
8
8
  module Binary
9
9
  module Records
10
- # EMR_PIXELFORMAT: header + body. Stub preserves bytes verbatim.
10
+ # Pixel format fields retain their original fixed-width descriptor bytes.
11
11
  class PixelFormat < Emf::Emr::Binary::Record
12
12
  rest :body
13
+
14
+ [
15
+ [:pfd_size, 0, "v", 2],
16
+ [:pfd_version, 2, "v", 2],
17
+ [:dw_flags, 4, "V", 4],
18
+ [:i_pixel_type, 8, "C", 1],
19
+ [:c_color_bits, 9, "C", 1],
20
+ [:c_red_bits, 10, "C", 1],
21
+ [:c_red_shift, 11, "C", 1],
22
+ [:c_green_bits, 12, "C", 1],
23
+ [:c_green_shift, 13, "C", 1],
24
+ [:c_blue_bits, 14, "C", 1],
25
+ [:c_blue_shift, 15, "C", 1],
26
+ [:c_alpha_bits, 16, "C", 1],
27
+ [:c_alpha_shift, 17, "C", 1],
28
+ [:c_accum_bits, 18, "C", 1],
29
+ [:c_accum_red_bits, 19, "C", 1],
30
+ [:c_accum_green_bits, 20, "C", 1],
31
+ [:c_accum_blue_bits, 21, "C", 1],
32
+ [:c_accum_alpha_bits, 22, "C", 1],
33
+ [:c_depth_bits, 23, "C", 1],
34
+ [:c_stencil_bits, 24, "C", 1],
35
+ [:c_aux_buffers, 25, "C", 1],
36
+ [:i_layer_type, 26, "C", 1],
37
+ [:b_reserved, 27, "C", 1],
38
+ [:dw_layer_mask, 28, "V", 4],
39
+ [:dw_visible_mask, 32, "V", 4],
40
+ [:dw_damage_mask, 36, "V", 4]
41
+ ].each do |name, offset, format, width|
42
+ define_method(name) do
43
+ pixel_format_body.byteslice(offset, width).unpack1(format)
44
+ end
45
+
46
+ define_method("#{name}=") do |value|
47
+ write_pixel_format_value(offset, value, format, width)
48
+ end
49
+ end
50
+
51
+ def pfd_bytes
52
+ pixel_format_body.byteslice(0, 40).b
53
+ end
54
+
55
+ def pfd_bytes=(value)
56
+ replace_pixel_format_bytes(0, 40, value)
57
+ end
58
+
59
+ private
60
+
61
+ def pixel_format_body
62
+ bytes = body.to_s
63
+ raise ArgumentError, "truncated pixel format descriptor" if bytes.bytesize < 40
64
+
65
+ bytes
66
+ end
67
+
68
+ def write_pixel_format_value(offset, value, format, width)
69
+ pixel_format_body
70
+ raise ArgumentError, "pixel format value must be an Integer" unless value.is_a?(Integer)
71
+
72
+ range = 0...(1 << (width * 8))
73
+ raise RangeError, "pixel format value must fit its #{width * 8}-bit field" unless range.cover?(value)
74
+
75
+ replace_pixel_format_bytes(offset, width, [value].pack(format))
76
+ end
77
+
78
+ def replace_pixel_format_bytes(offset, length, value)
79
+ bytes = pixel_format_body
80
+ unless value.is_a?(String) && value.bytesize == length
81
+ raise ArgumentError, "pixel format value must be a String of #{length} bytes"
82
+ end
83
+
84
+ replacement = bytes.b
85
+ replacement[offset, length] = value.b
86
+ self.body = replacement
87
+ end
13
88
  end
14
89
  end
15
90
  end
@@ -1,15 +1,81 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "bindata"
4
+ require "emf/emr/binary/variable_buffers"
4
5
  require "emf/emr/binary/with_bounds"
6
+ require "emf/emr/binary/dib_header"
5
7
 
6
8
  module Emf
7
9
  module Emr
8
10
  module Binary
9
11
  module Records
10
12
  # Stub: leading fields per MS-EMF, body captures remaining bytes.
13
+ # The fixed part is 140 bytes including the EMR header; the bitmap
14
+ # pointers are read from body without declaring fields.
11
15
  class PlgBlt < Emf::Emr::Binary::WithBounds
16
+ include Emf::Emr::Binary::VariableBuffers
17
+
18
+ fixed_layout 140
19
+ variable_buffer :bmi_bytes, offset: :off_bmi_src, length: :cb_bmi_src
20
+ variable_buffer :bits_bytes, offset: :off_bits_src, length: :cb_bits_src
21
+ variable_buffer :mask_bmi_bytes, offset: :off_bmi_mask, length: :cb_bmi_mask
22
+ variable_buffer :mask_bits_bytes, offset: :off_bits_mask, length: :cb_bits_mask
23
+
12
24
  rest :body
25
+
26
+ # Read-only accessors computed from body on each call; body starts at
27
+ # record offset 24, so a record offset maps to (offset - 24) in body.
28
+ def off_bmi_src
29
+ pointers(72)[0]
30
+ end
31
+
32
+ def cb_bmi_src
33
+ pointers(72)[1]
34
+ end
35
+
36
+ def off_bits_src
37
+ pointers(72)[2]
38
+ end
39
+
40
+ def cb_bits_src
41
+ pointers(72)[3]
42
+ end
43
+
44
+ def off_bmi_mask
45
+ pointers(100)[0]
46
+ end
47
+
48
+ def cb_bmi_mask
49
+ pointers(100)[1]
50
+ end
51
+
52
+ def off_bits_mask
53
+ pointers(100)[2]
54
+ end
55
+
56
+ def cb_bits_mask
57
+ pointers(100)[3]
58
+ end
59
+
60
+ def dib_header_view
61
+ DibHeader.view(off_bmi_src, cb_bmi_src, 140, after_fixed,
62
+ bits_offset: off_bits_src, bits_size: cb_bits_src)
63
+ end
64
+
65
+ def mask_dib_header_view
66
+ DibHeader.view(off_bmi_mask, cb_bmi_mask, 140, after_fixed,
67
+ bits_offset: off_bits_mask, bits_size: cb_bits_mask)
68
+ end
69
+
70
+ private
71
+
72
+ def after_fixed
73
+ body.to_s.byteslice(116..).to_s
74
+ end
75
+
76
+ def pointers(offset)
77
+ body.to_s.byteslice(offset, 16).to_s.unpack("V4").map(&:to_i)
78
+ end
13
79
  end
14
80
  end
15
81
  end