swfParser.ml 58 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258
  1. (*
  2. * This file is part of SwfLib
  3. * Copyright (c)2004 Nicolas Cannasse
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  18. *)
  19. open Swf
  20. open ActionScript
  21. open IO
  22. (* ************************************************************************ *)
  23. (* TOOLS *)
  24. let full_parsing = ref true
  25. let force_as3_parsing = ref false
  26. let swf_version = ref 0
  27. let id_count = ref 0
  28. let tag_end = { tid = 0; textended = false; tdata = TEnd }
  29. let sum f l =
  30. List.fold_left (fun acc x -> acc + f x) 0 l
  31. let gen_id() =
  32. incr id_count;
  33. !id_count
  34. let const n = fun _ -> n
  35. let opt_len f = function
  36. | None -> 0
  37. | Some x -> f x
  38. let opt_flag flags fid f fparam =
  39. if (flags land fid) = 0 then
  40. None
  41. else
  42. Some (f fparam)
  43. let opt f = function
  44. | None -> ()
  45. | Some x -> f x
  46. let flag = function
  47. | None -> false
  48. | Some _ -> true
  49. let rec make_flags = function
  50. | [] -> 0
  51. | true :: l -> 1 lor ((make_flags l) lsl 1)
  52. | false :: l -> (make_flags l) lsl 1
  53. let f16_value (a,b) =
  54. let k = int_of_char a lor (int_of_char b lsl 8) in
  55. float_of_int k /. float_of_int (1 lsl 8)
  56. let rec read_count n f arg =
  57. if n = 0 then
  58. []
  59. else
  60. let v = f arg in
  61. v :: read_count (n - 1) f arg
  62. (* ************************************************************************ *)
  63. (* LENGTH *)
  64. let _nbits x =
  65. if x < 0 then error "Negative nbits";
  66. if x = 0 then
  67. 0
  68. else
  69. let x = ref x in
  70. let nbits = ref 0 in
  71. while !x > 0 do
  72. x := !x lsr 1;
  73. incr nbits;
  74. done;
  75. !nbits
  76. let rect_nbits r =
  77. r.rect_nbits
  78. let bigrect_nbits r =
  79. r.brect_nbits
  80. let rgba_nbits c =
  81. max
  82. (max (_nbits c.r) (_nbits c.g))
  83. (max (_nbits c.b) (_nbits c.a))
  84. let cxa_nbits c =
  85. c.cxa_nbits
  86. let matrix_part_nbits m =
  87. m.m_nbits
  88. let rgb_length = 3
  89. let rgba_length = 4
  90. let string_length s = String.length s + 1
  91. let color_length = function
  92. | ColorRGB _ -> rgb_length
  93. | ColorRGBA _ -> rgba_length
  94. let rect_length r =
  95. let nbits = rect_nbits r in
  96. let nbits = nbits * 4 + 5 in
  97. (nbits + 7) / 8
  98. let big_rect_length r =
  99. let nbits = bigrect_nbits r in
  100. let nbits = nbits * 4 + 5 in
  101. (nbits + 7) / 8
  102. let gradient_length = function
  103. | GradientRGB (l,_) -> 1 + (1 + rgb_length) * List.length l
  104. | GradientRGBA (l,_) -> 1 + (1 + rgba_length) * List.length l
  105. let matrix_length m =
  106. let matrix_part_len m = 5 + matrix_part_nbits m * 2 in
  107. let nbits = 2 + opt_len matrix_part_len m.scale + opt_len matrix_part_len m.rotate + matrix_part_len m.trans in
  108. (nbits + 7) / 8
  109. let cxa_length c =
  110. let nbits = cxa_nbits c in
  111. let nbits = 6 + opt_len (const (nbits * 4)) c.cxa_add + opt_len (const (nbits * 4)) c.cxa_mult in
  112. (nbits + 7) / 8
  113. let clip_event_length c =
  114. (if !swf_version >= 6 then 4 else 2) + 4 + (opt_len (const 1) c.cle_key) + actions_length c.cle_actions
  115. let clip_events_length l =
  116. (if !swf_version >= 6 then 10 else 6) + sum clip_event_length l
  117. let export_length e =
  118. 2 + string_length e.exp_name
  119. let import_length i =
  120. 2 + string_length i.imp_name
  121. let sound_length s =
  122. 2 + 1 + 4 + String.length s.so_data
  123. let shape_fill_style_length s =
  124. 1 + match s with
  125. | SFSSolid _ -> rgb_length
  126. | SFSSolid3 _ -> rgba_length
  127. | SFSLinearGradient (m,g)
  128. | SFSRadialGradient (m,g,None) -> matrix_length m + gradient_length g
  129. | SFSRadialGradient (m,g,Some _) -> matrix_length m + gradient_length g + 2
  130. | SFSBitmap b -> 2 + matrix_length b.sfb_mpos
  131. let shape_line_style_length s =
  132. 2 + match s.sls_flags with
  133. | None -> color_length s.sls_color
  134. | Some _ ->
  135. 2 + (match s.sls_fill with None -> color_length s.sls_color | Some f -> shape_fill_style_length f)
  136. + opt_len (const 2) s.sls_miter
  137. let shape_array_length f s =
  138. let n = List.length s in
  139. (if n < 0xFF then 1 else 3) + sum f s
  140. let shape_new_styles_length s =
  141. shape_array_length shape_fill_style_length s.sns_fill_styles +
  142. shape_array_length shape_line_style_length s.sns_line_styles +
  143. 1
  144. let font_shape_records_length records =
  145. let nbits = ref 8 in
  146. let nfbits = ref records.srs_nfbits in
  147. let nlbits = ref records.srs_nlbits in
  148. List.iter (fun r ->
  149. nbits := !nbits + 6;
  150. match r with
  151. | SRStyleChange s ->
  152. nbits := !nbits +
  153. opt_len (fun (n,_,_) -> 5 + n * 2) s.scsr_move +
  154. opt_len (const !nfbits) s.scsr_fs0 +
  155. opt_len (const !nfbits) s.scsr_fs1 +
  156. opt_len (const !nlbits) s.scsr_ls;
  157. | SRCurvedEdge s ->
  158. nbits := !nbits + s.scer_nbits * 4
  159. | SRStraightEdge s ->
  160. nbits := !nbits + 1 + (match s.sser_line with
  161. | None , None -> assert false
  162. | Some _ , None
  163. | None, Some _ -> 1 + s.sser_nbits
  164. | Some _ , Some _ -> 2 * s.sser_nbits)
  165. ) records.srs_records;
  166. (* nbits := !nbits + 6; *)
  167. (!nbits + 7) / 8
  168. let shape_records_length records =
  169. let nbits = ref 8 in
  170. let nfbits = ref records.srs_nfbits in
  171. let nlbits = ref records.srs_nlbits in
  172. List.iter (fun r ->
  173. nbits := !nbits + 6;
  174. match r with
  175. | SRStyleChange s ->
  176. nbits := !nbits +
  177. opt_len (fun (n,_,_) -> 5 + n * 2) s.scsr_move +
  178. opt_len (const !nfbits) s.scsr_fs0 +
  179. opt_len (const !nfbits) s.scsr_fs1 +
  180. opt_len (const !nlbits) s.scsr_ls;
  181. (match s.scsr_new_styles with
  182. | None -> ()
  183. | Some s ->
  184. nbits := (((!nbits + 7) / 8) + shape_new_styles_length s) * 8;
  185. nfbits := s.sns_nfbits;
  186. nlbits := s.sns_nlbits)
  187. | SRCurvedEdge s ->
  188. nbits := !nbits + s.scer_nbits * 4
  189. | SRStraightEdge s ->
  190. nbits := !nbits + 1 + (match s.sser_line with
  191. | None , None -> assert false
  192. | Some _ , None
  193. | None, Some _ -> 1 + s.sser_nbits
  194. | Some _ , Some _ -> 2 * s.sser_nbits)
  195. ) records.srs_records;
  196. nbits := !nbits + 6;
  197. (!nbits + 7) / 8
  198. let shape_with_style_length s =
  199. shape_array_length shape_fill_style_length s.sws_fill_styles +
  200. shape_array_length shape_line_style_length s.sws_line_styles +
  201. shape_records_length s.sws_records
  202. let shape_length s =
  203. 2 + rect_length s.sh_bounds + opt_len (fun (r,_) -> rect_length r + 1) s.sh_bounds2 + shape_with_style_length s.sh_style
  204. let bitmap_lossless_length b =
  205. 2 + 1 + 2 + 2 + String.length b.bll_data
  206. let morph_shape_length s =
  207. 2 + rect_length s.msh_start_bounds + rect_length s.msh_end_bounds + String.length s.msh_data
  208. let text_record_length t r =
  209. 1 + opt_len (const 4) r.txr_font +
  210. opt_len color_length r.txr_color +
  211. opt_len (const 2) r.txr_dx +
  212. opt_len (const 2) r.txr_dy +
  213. 1 + ((((t.txt_ngbits + t.txt_nabits) * List.length r.txr_glyphs) + 7) / 8)
  214. let text_length t =
  215. 2 + big_rect_length t.txt_bounds + matrix_length t.txt_matrix + 2 + sum (text_record_length t) t.txt_records + 1
  216. let filters_length l =
  217. 1 + sum (fun f ->
  218. 1 + match f with
  219. | FDropShadow s
  220. | FBlur s
  221. | FGlow s
  222. | FBevel s
  223. | FAdjustColor s ->
  224. String.length s
  225. | FGradientGlow fg
  226. | FGradientBevel fg ->
  227. 1 + ((rgba_length + 1) * List.length fg.fgr_colors) + String.length fg.fgr_data
  228. ) l
  229. let button_record_length r =
  230. 1 + 2 + 2 + matrix_length r.btr_mpos + (match r.btr_color with None -> 0 | Some c -> cxa_length c)
  231. + opt_len filters_length r.btr_filters
  232. + (match r.btr_blendmode with None -> 0 | Some c -> 1)
  233. let button_action_length r =
  234. 2 + 2 + actions_length r.bta_actions
  235. let button2_length b =
  236. 2 + 1 + 2 +
  237. 1 + sum button_record_length b.bt2_records +
  238. sum button_action_length b.bt2_actions
  239. let cid_data_length c =
  240. 2 + String.length c.cd_data
  241. let edit_text_layout_length = 9
  242. let header_length h =
  243. 3 + 1 + rect_length h.h_size + 2 + 4
  244. let edit_text_length t =
  245. 2 + rect_length t.edt_bounds + 2 +
  246. opt_len (const 4) t.edt_font +
  247. opt_len (const rgba_length) t.edt_color +
  248. opt_len (const 2) t.edt_maxlen +
  249. opt_len (const edit_text_layout_length) t.edt_layout +
  250. string_length t.edt_variable +
  251. opt_len string_length t.edt_text
  252. let place_object_length p v3 =
  253. 3
  254. + (if v3 then 1 else 0)
  255. + 0 (* po_move *)
  256. + opt_len (const 2) p.po_cid
  257. + opt_len matrix_length p.po_matrix
  258. + opt_len cxa_length p.po_color
  259. + opt_len (const 2) p.po_ratio
  260. + opt_len string_length p.po_inst_name
  261. + opt_len (const 2) p.po_clip_depth
  262. + opt_len clip_events_length p.po_events
  263. + (if v3 then
  264. opt_len filters_length p.po_filters
  265. + opt_len (const 1) p.po_blend
  266. + opt_len (const 1) p.po_bcache
  267. else
  268. 0)
  269. let rec tag_data_length = function
  270. | TEnd ->
  271. 0
  272. | TShowFrame ->
  273. 0
  274. | TShape s ->
  275. shape_length s
  276. | TRemoveObject _ ->
  277. 4
  278. | TBitsJPEG b ->
  279. 2 + String.length b.jpg_data
  280. | TJPEGTables tab ->
  281. String.length tab
  282. | TSetBgColor _ ->
  283. rgb_length
  284. | TFont c ->
  285. cid_data_length c
  286. | TText t ->
  287. text_length t
  288. | TDoAction acts ->
  289. actions_length acts
  290. | TFontInfo c ->
  291. cid_data_length c
  292. | TSound s ->
  293. sound_length s
  294. | TStartSound s ->
  295. 2 + String.length s.sts_data
  296. | TBitsLossless b ->
  297. bitmap_lossless_length b
  298. | TBitsJPEG2 b ->
  299. 2 + opt_len String.length b.bd_table + String.length b.bd_data
  300. | TShape2 s ->
  301. shape_length s
  302. | TProtect ->
  303. 0
  304. | TPlaceObject2 p ->
  305. place_object_length p false
  306. | TRemoveObject2 _ ->
  307. 2
  308. | TShape3 s ->
  309. shape_length s
  310. | TText2 t ->
  311. text_length t
  312. | TButton2 b ->
  313. button2_length b
  314. | TBitsJPEG3 b ->
  315. 2 + 4 + opt_len String.length b.bd_table + String.length b.bd_data + opt_len String.length b.bd_alpha
  316. | TBitsLossless2 b ->
  317. bitmap_lossless_length b
  318. | TEditText t ->
  319. edit_text_length t
  320. | TClip c ->
  321. 4 + sum tag_length (tag_end :: c.c_tags)
  322. | TProductInfo s ->
  323. String.length s
  324. | TFrameLabel (label,id) ->
  325. string_length label + (match id with None -> 0 | Some _ -> 1)
  326. | TSoundStreamHead2 data ->
  327. String.length data
  328. | TMorphShape s | TMorphShape2 s ->
  329. morph_shape_length s
  330. | TFont2 c | TFont3 c | TFontAlignZones c ->
  331. cid_data_length c
  332. | TExport el ->
  333. 2 + sum export_length el
  334. | TImport (url,il) ->
  335. string_length url + 2 + sum import_length il
  336. | TDoInitAction i ->
  337. 2 + actions_length i.dia_actions
  338. | TVideoStream c ->
  339. cid_data_length c
  340. | TVideoFrame c ->
  341. cid_data_length c
  342. | TFontInfo2 c ->
  343. cid_data_length c
  344. | TDebugID s ->
  345. String.length s
  346. | TEnableDebugger2 (_,pass) ->
  347. 2 + string_length pass
  348. | TScriptLimits _ ->
  349. 4
  350. | TFilesAttributes _ ->
  351. 4
  352. | TPlaceObject3 p ->
  353. place_object_length p true
  354. | TImport2 (url,il) ->
  355. string_length url + 1 + 1 + 2 + sum import_length il
  356. | TCSMSettings c ->
  357. cid_data_length c
  358. | TF9Classes l ->
  359. 2 + sum (fun c -> string_length c.f9_classname + 2) l
  360. | TMetaData meta ->
  361. string_length meta
  362. | TScale9 (_,r) ->
  363. 2 + rect_length r
  364. | TActionScript3 (id,a) ->
  365. (match id with None -> 0 | Some (id,f) -> 4 + string_length f) + As3parse.as3_length a
  366. | TShape4 s ->
  367. shape_length s
  368. | TScenes (sl,fl) ->
  369. As3parse.int_length (List.length sl) + sum (fun(n,s) -> As3parse.int_length n + string_length s) sl +
  370. As3parse.int_length (List.length fl) + sum (fun(n,s) -> As3parse.int_length n + string_length s) fl
  371. | TBinaryData (_,data) ->
  372. 2 + 4 + String.length data
  373. | TBigBinaryData (_,data) ->
  374. 2 + 4 + (List.fold_left (fun acc s -> acc + String.length s) 0 data)
  375. | TFontName c ->
  376. cid_data_length c
  377. | TBitsJPEG4 b ->
  378. 2 + 2 + 4 + opt_len String.length b.bd_table + String.length b.bd_data + opt_len String.length b.bd_alpha
  379. | TFont4 c ->
  380. cid_data_length c
  381. | TUnknown (_,data) ->
  382. String.length data
  383. and tag_length t =
  384. let dlen = tag_data_length t.tdata in
  385. dlen + 2 + (if t.textended || dlen >= 63 then 4 else 0)
  386. (* ************************************************************************ *)
  387. (* READ PRIMS *)
  388. let skip ch n =
  389. seek_in ch ((Pervasives.pos_in ch) + n)
  390. let read_rgba ch =
  391. let r = read_byte ch in
  392. let g = read_byte ch in
  393. let b = read_byte ch in
  394. let a = read_byte ch in
  395. {
  396. r = r;
  397. g = g;
  398. b = b;
  399. a = a;
  400. }
  401. let read_rgb ch =
  402. let r = read_byte ch in
  403. let g = read_byte ch in
  404. let b = read_byte ch in
  405. {
  406. cr = r;
  407. cg = g;
  408. cb = b;
  409. }
  410. let read_gradient ch is_rgba =
  411. let grad_rgb() =
  412. let r = read_byte ch in
  413. let c = read_rgb ch in
  414. (r, c)
  415. in
  416. let grad_rgba() =
  417. let r = read_byte ch in
  418. let c = read_rgba ch in
  419. (r, c)
  420. in
  421. let n = read_byte ch in
  422. let n , flags = n land 0xF , n lsr 4 in
  423. if is_rgba then
  424. GradientRGBA (read_count n grad_rgba (),flags)
  425. else
  426. GradientRGB (read_count n grad_rgb (),flags)
  427. let read_rect ch =
  428. let b = input_bits ch in
  429. let nbits = read_bits b 5 in
  430. let left = read_bits b nbits in
  431. let right = read_bits b nbits in
  432. let top = read_bits b nbits in
  433. let bottom = read_bits b nbits in
  434. {
  435. rect_nbits = nbits;
  436. left = left;
  437. right = right;
  438. top = top;
  439. bottom = bottom;
  440. }
  441. let rec read_multi_bits b n =
  442. if n <= 30 then
  443. [read_bits b n]
  444. else
  445. let d = read_bits b 30 in
  446. d :: read_multi_bits b (n - 30)
  447. let read_big_rect ch =
  448. let b = input_bits ch in
  449. let nbits = read_bits b 5 in
  450. let left = read_multi_bits b nbits in
  451. let right = read_multi_bits b nbits in
  452. let top = read_multi_bits b nbits in
  453. let bottom = read_multi_bits b nbits in
  454. {
  455. brect_nbits = nbits;
  456. bleft = left;
  457. bright = right;
  458. btop = top;
  459. bbottom = bottom;
  460. }
  461. let read_matrix ch =
  462. let b = input_bits ch in
  463. let read_matrix_part() =
  464. let nbits = read_bits b 5 in
  465. let x = read_bits b nbits in
  466. let y = read_bits b nbits in
  467. {
  468. m_nbits = nbits;
  469. mx = x;
  470. my = y;
  471. }
  472. in
  473. let has_scale = (read_bits b 1 = 1) in
  474. let scale = (if has_scale then Some (read_matrix_part()) else None) in
  475. let has_rotate = (read_bits b 1 = 1) in
  476. let rotate = (if has_rotate then Some (read_matrix_part()) else None) in
  477. let trans = read_matrix_part() in
  478. {
  479. scale = scale;
  480. rotate = rotate;
  481. trans = trans;
  482. }
  483. let read_cxa ch =
  484. let b = input_bits ch in
  485. let has_add = (read_bits b 1 = 1) in
  486. let has_mult = (read_bits b 1 = 1) in
  487. let nbits = read_bits b 4 in
  488. let read_cxa_color() =
  489. let r = read_bits b nbits in
  490. let g = read_bits b nbits in
  491. let bl = read_bits b nbits in
  492. let a = read_bits b nbits in
  493. {
  494. r = r;
  495. g = g;
  496. b = bl;
  497. a = a;
  498. }
  499. in
  500. let mult = (if has_mult then Some (read_cxa_color()) else None) in
  501. let add = (if has_add then Some (read_cxa_color()) else None) in
  502. {
  503. cxa_nbits = nbits;
  504. cxa_add = add;
  505. cxa_mult = mult;
  506. }
  507. let read_event ch =
  508. (if !swf_version >= 6 then read_i32 else read_ui16) ch
  509. (* ************************************************************************ *)
  510. (* WRITE PRIMS *)
  511. let write_rgb ch c =
  512. write_byte ch c.cr;
  513. write_byte ch c.cg;
  514. write_byte ch c.cb
  515. let write_rgba ch c =
  516. write_byte ch c.r;
  517. write_byte ch c.g;
  518. write_byte ch c.b;
  519. write_byte ch c.a
  520. let write_color ch = function
  521. | ColorRGB c -> write_rgb ch c
  522. | ColorRGBA c -> write_rgba ch c
  523. let write_gradient ch = function
  524. | GradientRGB (l,flags) ->
  525. let n = List.length l in
  526. write_byte ch (n lor (flags lsl 4));
  527. List.iter (fun (ratio,c) -> write_byte ch ratio; write_rgb ch c) l
  528. | GradientRGBA (l,flags) ->
  529. let n = List.length l in
  530. write_byte ch (n lor (flags lsl 4));
  531. List.iter (fun (ratio,c) -> write_byte ch ratio; write_rgba ch c) l
  532. let write_rect ch r =
  533. let b = output_bits ch in
  534. let nbits = rect_nbits r in
  535. write_bits b 5 nbits;
  536. write_bits b nbits r.left;
  537. write_bits b nbits r.right;
  538. write_bits b nbits r.top;
  539. write_bits b nbits r.bottom;
  540. flush_bits b
  541. let rec write_multi_bits b n l =
  542. if n <= 30 then
  543. match l with
  544. | [] -> write_bits b n 0
  545. | [x] -> write_bits b n x
  546. | _ -> assert false
  547. else
  548. match l with
  549. | [] -> write_bits b 30 0; write_multi_bits b (n - 30) []
  550. | x :: l -> write_bits b 30 x; write_multi_bits b (n - 30) l
  551. let write_big_rect ch r =
  552. let b = output_bits ch in
  553. let nbits = bigrect_nbits r in
  554. write_bits b 5 nbits;
  555. write_multi_bits b nbits r.bleft;
  556. write_multi_bits b nbits r.bright;
  557. write_multi_bits b nbits r.btop;
  558. write_multi_bits b nbits r.bbottom;
  559. flush_bits b
  560. let write_matrix ch m =
  561. let b = output_bits ch in
  562. let write_matrix_part m =
  563. let nbits = matrix_part_nbits m in
  564. write_bits b 5 nbits;
  565. write_bits b nbits m.mx;
  566. write_bits b nbits m.my;
  567. in
  568. (match m.scale with
  569. | None ->
  570. write_bits b 1 0
  571. | Some s ->
  572. write_bits b 1 1;
  573. write_matrix_part s
  574. );
  575. (match m.rotate with
  576. | None ->
  577. write_bits b 1 0
  578. | Some r ->
  579. write_bits b 1 1;
  580. write_matrix_part r);
  581. write_matrix_part m.trans;
  582. flush_bits b
  583. let write_cxa ch c =
  584. let b = output_bits ch in
  585. let nbits = cxa_nbits c in
  586. (match c.cxa_add , c.cxa_mult with
  587. | None , None ->
  588. write_bits b 2 0;
  589. write_bits b 4 1; (* some strange MM thing... *)
  590. | Some c , None ->
  591. write_bits b 2 2;
  592. write_bits b 4 nbits;
  593. List.iter (write_bits b ~nbits) [c.r;c.g;c.b;c.a];
  594. | None , Some c ->
  595. write_bits b 2 1;
  596. write_bits b 4 nbits;
  597. List.iter (write_bits b ~nbits) [c.r;c.g;c.b;c.a];
  598. | Some c1 , Some c2 ->
  599. write_bits b 2 3;
  600. write_bits b 4 nbits;
  601. List.iter (write_bits b ~nbits) [c2.r;c2.g;c2.b;c2.a;c1.r;c1.g;c1.b;c1.a]
  602. );
  603. flush_bits b
  604. let write_event ch evt =
  605. (if !swf_version >= 6 then write_i32 else write_ui16) ch evt
  606. (* ************************************************************************ *)
  607. (* PARSING *)
  608. let parse_clip_events ch =
  609. ignore(read_ui16 ch); (* reserved *)
  610. ignore(read_event ch); (* all_events *)
  611. let rec loop() =
  612. let events = read_event ch in
  613. if events = 0 then
  614. []
  615. else begin
  616. ignore(read_i32 ch); (* len *)
  617. let key = (if events land (1 lsl 17) <> 0 then Some (read ch) else None) in
  618. let e = {
  619. cle_events = events;
  620. cle_key = key;
  621. cle_actions = parse_actions ch
  622. } in
  623. e :: (loop())
  624. end;
  625. in
  626. loop()
  627. let parse_shape_fill_style ch vshape =
  628. let t = read_byte ch in
  629. match t with
  630. | 0x00 when vshape >= 3 -> SFSSolid3 (read_rgba ch)
  631. | 0x00 -> SFSSolid (read_rgb ch)
  632. | 0x10 ->
  633. let m = read_matrix ch in
  634. let g = read_gradient ch (vshape >= 3) in
  635. SFSLinearGradient (m,g)
  636. | 0x12 ->
  637. let m = read_matrix ch in
  638. let g = read_gradient ch (vshape >= 3) in
  639. SFSRadialGradient (m,g,None)
  640. | 0x13 ->
  641. let m = read_matrix ch in
  642. let g = read_gradient ch (vshape >= 3) in
  643. let i = read_i16 ch in
  644. SFSRadialGradient (m,g,Some i)
  645. | 0x40
  646. | 0x41
  647. | 0x42
  648. | 0x43 ->
  649. let id = read_ui16 ch in
  650. let m = read_matrix ch in
  651. SFSBitmap {
  652. sfb_repeat = (t = 0x40 || t = 0x42);
  653. sfb_smooth = (t = 0x42 || t = 0x43);
  654. sfb_cid = id;
  655. sfb_mpos = m;
  656. }
  657. | _ ->
  658. assert false
  659. let parse_shape_line_style ch vshape =
  660. let width = read_ui16 ch in
  661. if vshape >= 4 then begin
  662. let flags = read_ui16 ch in
  663. let fill = (flags land 8 <> 0) in
  664. let miterjoin = (flags land 0x20 <> 0) in
  665. let miter = (if miterjoin then Some (IO.read_ui16 ch) else None) in
  666. let color = (if fill then { r = 0; g = 0; b = 0; a = 0 } else read_rgba ch) in
  667. (*
  668. let noVscale = (flags land 0x02 <> 0) in
  669. let noHscale = (flags land 0x04 <> 0) in
  670. let beveljoin = (flags land 0x10 <> 0) in
  671. let nocap = (flags land 0x40 <> 0) in
  672. let squarecap = (flags land 0x80 <> 0) in
  673. *)
  674. {
  675. sls_width = width;
  676. sls_color = ColorRGBA color;
  677. sls_fill = if fill then Some (parse_shape_fill_style ch vshape) else None;
  678. sls_flags = Some flags;
  679. sls_miter = miter;
  680. }
  681. end else
  682. {
  683. sls_width = width;
  684. sls_color = if vshape = 3 then ColorRGBA (read_rgba ch) else ColorRGB (read_rgb ch);
  685. sls_fill = None;
  686. sls_flags = None;
  687. sls_miter = None;
  688. }
  689. let parse_shape_array f ch vshape =
  690. let n = (match read_byte ch with 0xFF -> read_ui16 ch | n -> n) in
  691. read_count n (f ch) vshape
  692. let parse_shape_style_change_record ch b flags nlbits nfbits vshape =
  693. let move = (if flags land 1 <> 0 then begin
  694. let mbits = read_bits b 5 in
  695. let dx = read_bits b mbits in
  696. let dy = read_bits b mbits in
  697. Some (mbits,dx,dy)
  698. end else
  699. None)
  700. in
  701. let fs0 = (if flags land 2 <> 0 then Some (read_bits b !nfbits) else None) in
  702. let fs1 = (if flags land 4 <> 0 then Some (read_bits b !nfbits) else None) in
  703. let ls = (if flags land 8 <> 0 then Some (read_bits b !nlbits) else None) in
  704. let styles = (if flags land 16 <> 0 then begin
  705. IO.drop_bits b;
  706. let fstyles = parse_shape_array parse_shape_fill_style ch vshape in
  707. let lstyles = parse_shape_array parse_shape_line_style ch vshape in
  708. let bits = read_byte ch in
  709. nlbits := bits land 15;
  710. nfbits := bits lsr 4;
  711. Some {
  712. sns_fill_styles = fstyles;
  713. sns_line_styles = lstyles;
  714. sns_nlbits = !nlbits;
  715. sns_nfbits = !nfbits;
  716. }
  717. end else
  718. None
  719. ) in
  720. {
  721. scsr_move = move;
  722. scsr_fs0 = fs0;
  723. scsr_fs1 = fs1;
  724. scsr_ls = ls;
  725. scsr_new_styles = styles;
  726. }
  727. let parse_shape_curved_edge_record b flags =
  728. let nbits = (flags land 15) + 2 in
  729. let cx = read_bits b nbits in
  730. let cy = read_bits b nbits in
  731. let ax = read_bits b nbits in
  732. let ay = read_bits b nbits in
  733. {
  734. scer_nbits = nbits;
  735. scer_cx = cx;
  736. scer_cy = cy;
  737. scer_ax = ax;
  738. scer_ay = ay;
  739. }
  740. let parse_shape_straight_edge_record b flags =
  741. let nbits = (flags land 15) + 2 in
  742. let is_general = (read_bits b 1 = 1) in
  743. let l = (if is_general then
  744. let dx = read_bits b nbits in
  745. let dy = read_bits b nbits in
  746. Some dx, Some dy
  747. else
  748. let is_vertical = (read_bits b 1 = 1) in
  749. let p = read_bits b nbits in
  750. if is_vertical then
  751. None, Some p
  752. else
  753. Some p, None)
  754. in
  755. {
  756. sser_nbits = nbits;
  757. sser_line = l;
  758. }
  759. let parse_shape_records ch nlbits nfbits vshape =
  760. let b = input_bits ch in
  761. let nlbits = ref nlbits in
  762. let nfbits = ref nfbits in
  763. let rec loop() =
  764. let flags = read_bits b 6 in
  765. if flags = 0 then
  766. []
  767. else
  768. let r =
  769. (if (flags land 32) = 0 then
  770. SRStyleChange (parse_shape_style_change_record ch b flags nlbits nfbits vshape)
  771. else if (flags land 48) = 32 then
  772. SRCurvedEdge (parse_shape_curved_edge_record b flags)
  773. else
  774. SRStraightEdge (parse_shape_straight_edge_record b flags))
  775. in
  776. r :: loop()
  777. in
  778. loop()
  779. let parse_shape_with_style ch vshape =
  780. let fstyles = parse_shape_array parse_shape_fill_style ch vshape in
  781. let lstyles = parse_shape_array parse_shape_line_style ch vshape in
  782. let bits = read_byte ch in
  783. let nlbits = bits land 15 in
  784. let nfbits = bits lsr 4 in
  785. let records = parse_shape_records ch nlbits nfbits vshape in
  786. {
  787. sws_fill_styles = fstyles;
  788. sws_line_styles = lstyles;
  789. sws_records = {
  790. srs_nlbits = nlbits;
  791. srs_nfbits = nfbits;
  792. srs_records = records;
  793. }
  794. }
  795. let parse_shape ch len vshape =
  796. let id = read_ui16 ch in
  797. let bounds = read_rect ch in
  798. let bounds2 = (if vshape = 4 then
  799. let r = read_rect ch in
  800. let b = read_byte ch in
  801. Some (r, b)
  802. else
  803. None
  804. ) in
  805. let style = parse_shape_with_style ch vshape in
  806. {
  807. sh_id = id;
  808. sh_bounds = bounds;
  809. sh_bounds2 = bounds2;
  810. sh_style = style;
  811. }
  812. let extract_jpg_table data =
  813. match data.[0], data.[1] with
  814. | '\xFF', '\xD8' ->
  815. let ch = IO.input_string data in
  816. let b = Buffer.create 0 in
  817. let rec loop flag =
  818. let c = IO.read ch in
  819. Buffer.add_char b c;
  820. match int_of_char c with
  821. | 0xFF -> loop true
  822. | 0xD9 when flag -> ()
  823. | _ -> loop false
  824. in
  825. loop false;
  826. let t = Buffer.contents b in
  827. let l = String.length t in
  828. String.sub data l (String.length data - l), Some t
  829. | _ ->
  830. data, None
  831. let parse_bitmap_lossless ch len =
  832. let id = read_ui16 ch in
  833. let format = read_byte ch in
  834. let width = read_ui16 ch in
  835. let height = read_ui16 ch in
  836. let data = nread_string ch (len - 7) in
  837. {
  838. bll_id = id;
  839. bll_format = format;
  840. bll_width = width;
  841. bll_height = height;
  842. bll_data = data;
  843. }
  844. let parse_text ch is_txt2 =
  845. let id = read_ui16 ch in
  846. let bounds = read_big_rect ch in
  847. let matrix = read_matrix ch in
  848. let ngbits = read_byte ch in
  849. let nabits = read_byte ch in
  850. let read_glyph bits =
  851. let indx = read_bits bits ngbits in
  852. let adv = read_bits bits nabits in
  853. {
  854. txg_index = indx;
  855. txg_advanced = adv;
  856. }
  857. in
  858. let rec loop() =
  859. let flags = read_byte ch in
  860. if flags = 0 then
  861. []
  862. else
  863. let font_id = (if flags land 8 <> 0 then read_ui16 ch else 0) in
  864. let color = (if flags land 4 <> 0 then Some (if is_txt2 then ColorRGBA (read_rgba ch) else ColorRGB (read_rgb ch)) else None) in
  865. let dx = (if flags land 1 <> 0 then Some (read_i16 ch) else None) in
  866. let dy = (if flags land 2 <> 0 then Some (read_i16 ch) else None) in
  867. let font = (if flags land 8 <> 0 then Some (font_id,read_ui16 ch) else None) in
  868. let nglyphs = read_byte ch in
  869. let r = {
  870. txr_font = font;
  871. txr_color = color;
  872. txr_dx = dx;
  873. txr_dy = dy;
  874. txr_glyphs = read_count nglyphs read_glyph (input_bits ch);
  875. } in
  876. r :: loop()
  877. in
  878. {
  879. txt_id = id;
  880. txt_bounds = bounds;
  881. txt_matrix = matrix;
  882. txt_ngbits = ngbits;
  883. txt_nabits = nabits;
  884. txt_records = loop();
  885. }
  886. let parse_edit_text_layout ch =
  887. let align = read_byte ch in
  888. let ml = read_ui16 ch in
  889. let rl = read_ui16 ch in
  890. let ident = read_ui16 ch in
  891. let lead = read_ui16 ch in
  892. {
  893. edtl_align = align;
  894. edtl_left_margin = ml;
  895. edtl_right_margin = rl;
  896. edtl_indent = ident;
  897. edtl_leading = lead;
  898. }
  899. let parse_edit_text ch =
  900. let id = read_ui16 ch in
  901. let bounds = read_rect ch in
  902. let flags = read_ui16 ch in
  903. let font = (if flags land 1 <> 0 then
  904. let fid = read_ui16 ch in
  905. let height = read_ui16 ch in
  906. Some (fid, height)
  907. else
  908. None) in
  909. let color = (if flags land 4 <> 0 then Some (read_rgba ch) else None) in
  910. let maxlen = (if flags land 2 <> 0 then Some (read_ui16 ch) else None) in
  911. let layout = (if flags land (1 lsl 13) <> 0 then Some (parse_edit_text_layout ch) else None) in
  912. let variable = read_string ch in
  913. let text = (if flags land 128 <> 0 then Some (read_string ch) else None) in
  914. {
  915. edt_id = id;
  916. edt_bounds = bounds;
  917. edt_font = font;
  918. edt_color = color;
  919. edt_maxlen = maxlen;
  920. edt_layout = layout;
  921. edt_variable = variable;
  922. edt_text = text;
  923. edt_wordwrap = (flags land 64) <> 0;
  924. edt_multiline = (flags land 32) <> 0;
  925. edt_password = (flags land 16) <> 0;
  926. edt_readonly = (flags land 8) <> 0;
  927. edt_autosize = (flags land (1 lsl 14)) <> 0;
  928. edt_noselect = (flags land 4096) <> 0;
  929. edt_border = (flags land 2048) <> 0;
  930. edt_html = (flags land 512) <> 0;
  931. edt_outlines = (flags land 256) <> 0;
  932. }
  933. let parse_cid_data ch len =
  934. let id = read_ui16 ch in
  935. let data = nread_string ch (len - 2) in
  936. {
  937. cd_id = id;
  938. cd_data = data;
  939. }
  940. let parse_morph_shape ch len =
  941. let id = read_ui16 ch in
  942. let sbounds = read_rect ch in
  943. let ebounds = read_rect ch in
  944. let data = nread_string ch (len - 2 - rect_length sbounds - rect_length ebounds) in
  945. {
  946. msh_id = id;
  947. msh_start_bounds = sbounds;
  948. msh_end_bounds = ebounds;
  949. msh_data = data;
  950. }
  951. let parse_filter_gradient ch =
  952. let ncolors = read_byte ch in
  953. let colors = read_count ncolors read_rgba ch in
  954. let cvals = read_count ncolors read_byte ch in
  955. let data = nread_string ch 19 in
  956. {
  957. fgr_colors = List.combine colors cvals;
  958. fgr_data = data;
  959. }
  960. let parse_filter ch =
  961. match read_byte ch with
  962. | 0 -> FDropShadow (nread_string ch 23)
  963. | 1 -> FBlur (nread_string ch 9)
  964. | 2 -> FGlow (nread_string ch 15)
  965. | 3 -> FBevel (nread_string ch 27)
  966. | 4 -> FGradientGlow (parse_filter_gradient ch)
  967. | 6 -> FAdjustColor (nread_string ch 80)
  968. | 7 -> FGradientBevel (parse_filter_gradient ch)
  969. | _ -> assert false
  970. let parse_filters ch =
  971. let nf = read_byte ch in
  972. read_count nf parse_filter ch
  973. let rec parse_button_records ch color =
  974. let flags = read_byte ch in
  975. if flags = 0 then
  976. []
  977. else
  978. let cid = read_ui16 ch in
  979. let depth = read_ui16 ch in
  980. let mpos = read_matrix ch in
  981. let cxa = (if color then Some (read_cxa ch) else None) in
  982. let filters = (if flags land 16 = 0 then None else Some (parse_filters ch)) in
  983. let blendmode = (if flags land 32 = 0 then None else Some (read_byte ch)) in
  984. let r = {
  985. btr_flags = flags;
  986. btr_cid = cid;
  987. btr_depth = depth;
  988. btr_mpos = mpos;
  989. btr_color = cxa;
  990. btr_filters = filters;
  991. btr_blendmode = blendmode;
  992. } in
  993. r :: parse_button_records ch color
  994. let rec parse_button_actions ch =
  995. let size = read_ui16 ch in
  996. let flags = read_ui16 ch in
  997. let actions = parse_actions ch in
  998. let bta = {
  999. bta_flags = flags;
  1000. bta_actions = actions;
  1001. } in
  1002. if size = 0 then
  1003. [bta]
  1004. else
  1005. bta :: parse_button_actions ch
  1006. let parse_button2 ch len =
  1007. let id = read_ui16 ch in
  1008. let flags = read_byte ch in
  1009. let track = (match flags with 0 -> false | 1 -> true | _ -> assert false) in
  1010. let offset = read_ui16 ch in
  1011. let records = parse_button_records ch true in
  1012. let actions = (if offset = 0 then [] else parse_button_actions ch) in
  1013. {
  1014. bt2_id = id;
  1015. bt2_track_as_menu = track;
  1016. bt2_records = records;
  1017. bt2_actions = actions;
  1018. }
  1019. let parse_place_object ch v3 =
  1020. let f = read_byte ch in
  1021. let fext = (if v3 then read_byte ch else 0) in
  1022. let depth = read_ui16 ch in
  1023. let move = (f land 1) <> 0 in
  1024. let cid = opt_flag f 2 read_ui16 ch in
  1025. let matrix = opt_flag f 4 read_matrix ch in
  1026. let color = opt_flag f 8 read_cxa ch in
  1027. let ratio = opt_flag f 16 read_ui16 ch in
  1028. let name = opt_flag f 32 read_string ch in
  1029. let clip_depth = opt_flag f 64 read_ui16 ch in
  1030. let clip_events = opt_flag f 128 parse_clip_events ch in
  1031. let filters = opt_flag fext 1 parse_filters ch in
  1032. let blend = opt_flag fext 2 read_byte ch in
  1033. let bcache = opt_flag fext 4 read_byte ch in
  1034. {
  1035. po_depth = depth;
  1036. po_move = move;
  1037. po_cid = cid;
  1038. po_matrix = matrix;
  1039. po_color = color;
  1040. po_ratio = ratio;
  1041. po_inst_name = name;
  1042. po_clip_depth = clip_depth;
  1043. po_events = clip_events;
  1044. po_filters = filters;
  1045. po_blend = blend;
  1046. po_bcache = bcache;
  1047. }
  1048. let parse_import ch =
  1049. let cid = read_ui16 ch in
  1050. let name = read_string ch in
  1051. {
  1052. imp_id = cid;
  1053. imp_name = name
  1054. }
  1055. let rec parse_tag ch h =
  1056. let id = h lsr 6 in
  1057. let len = h land 63 in
  1058. let len , extended = (
  1059. if len = 63 then
  1060. let len = read_i32 ch in
  1061. len , len < 63
  1062. else
  1063. len , false
  1064. ) in
  1065. let t = (
  1066. match id with
  1067. | 0x00 ->
  1068. TEnd
  1069. | 0x01 ->
  1070. TShowFrame
  1071. | 0x02 when !full_parsing ->
  1072. TShape (parse_shape ch len 1)
  1073. (* 0x03 invalid *)
  1074. (*//0x04 TPlaceObject *)
  1075. | 0x05 ->
  1076. let cid = read_ui16 ch in
  1077. let depth = read_ui16 ch in
  1078. TRemoveObject {
  1079. rmo_id = cid;
  1080. rmo_depth = depth;
  1081. }
  1082. | 0x06 ->
  1083. let id = read_ui16 ch in
  1084. let data = nread_string ch (len - 2) in
  1085. TBitsJPEG {
  1086. jpg_id = id;
  1087. jpg_data = data;
  1088. }
  1089. (*//0x07 TButton *)
  1090. | 0x08 ->
  1091. TJPEGTables (nread_string ch len)
  1092. | 0x09 ->
  1093. TSetBgColor (read_rgb ch)
  1094. | 0x0A ->
  1095. TFont (parse_cid_data ch len)
  1096. | 0x0B when !full_parsing ->
  1097. TText (parse_text ch false)
  1098. | 0x0C ->
  1099. TDoAction (parse_actions ch)
  1100. | 0x0D ->
  1101. TFontInfo (parse_cid_data ch len)
  1102. | 0x0E ->
  1103. let sid = read_ui16 ch in
  1104. let flags = read_byte ch in
  1105. let samples = read_i32 ch in
  1106. let data = nread_string ch (len - 7) in
  1107. TSound {
  1108. so_id = sid;
  1109. so_flags = flags;
  1110. so_samples = samples;
  1111. so_data = data;
  1112. }
  1113. | 0x0F ->
  1114. let sid = read_ui16 ch in
  1115. let data = nread_string ch (len - 2) in
  1116. TStartSound {
  1117. sts_id = sid;
  1118. sts_data = data;
  1119. }
  1120. (* 0x10 invalid *)
  1121. (*//0x11 TButtonSound *)
  1122. (*//0x12 TSoundStreamHead *)
  1123. (*//0x13 TSoundStreamBlock *)
  1124. | 0x14 ->
  1125. TBitsLossless (parse_bitmap_lossless ch len)
  1126. | 0x15 ->
  1127. let id = read_ui16 ch in
  1128. let data = nread_string ch (len - 2) in
  1129. let data, table = extract_jpg_table data in
  1130. TBitsJPEG2 {
  1131. bd_id = id;
  1132. bd_table = table;
  1133. bd_data = data;
  1134. bd_alpha = None;
  1135. bd_deblock = None;
  1136. }
  1137. | 0x16 when !full_parsing ->
  1138. TShape2 (parse_shape ch len 2)
  1139. (*//0x17 TButtonCXForm *)
  1140. | 0x18 ->
  1141. TProtect
  1142. (* 0x19 invalid *)
  1143. | 0x1A when !full_parsing ->
  1144. TPlaceObject2 (parse_place_object ch false)
  1145. (* 0x1B invalid *)
  1146. | 0x1C ->
  1147. let depth = read_ui16 ch in
  1148. TRemoveObject2 depth
  1149. (* 0x1D-1F invalid *)
  1150. | 0x20 when !full_parsing ->
  1151. TShape3 (parse_shape ch len 3)
  1152. | 0x21 when !full_parsing ->
  1153. TText2 (parse_text ch true)
  1154. | 0x22 when !full_parsing ->
  1155. TButton2 (parse_button2 ch len)
  1156. | 0x23 ->
  1157. let id = read_ui16 ch in
  1158. let size = read_i32 ch in
  1159. let data = nread_string ch size in
  1160. let data, table = extract_jpg_table data in
  1161. let alpha = nread_string ch (len - 6 - size) in
  1162. TBitsJPEG3 {
  1163. bd_id = id;
  1164. bd_table = table;
  1165. bd_data = data;
  1166. bd_alpha = Some alpha;
  1167. bd_deblock = None;
  1168. }
  1169. | 0x24 ->
  1170. TBitsLossless2 (parse_bitmap_lossless ch len)
  1171. | 0x25 when !full_parsing ->
  1172. TEditText (parse_edit_text ch)
  1173. (* 0x26 invalid *)
  1174. | 0x27 ->
  1175. let cid = read_ui16 ch in
  1176. let fcount = read_ui16 ch in
  1177. let tags = parse_tag_list ch in
  1178. TClip {
  1179. c_id = cid;
  1180. c_frame_count = fcount;
  1181. c_tags = tags;
  1182. }
  1183. (* 0x28 invalid *)
  1184. | 0x29 ->
  1185. (* undocumented ? *)
  1186. TProductInfo (nread_string ch len)
  1187. (* 0x2A invalid *)
  1188. | 0x2B ->
  1189. let label = read_string ch in
  1190. let id = (if len = String.length label + 2 then Some (read ch) else None) in
  1191. TFrameLabel (label,id)
  1192. (* 0x2C invalid *)
  1193. | 0x2D ->
  1194. TSoundStreamHead2 (nread_string ch len)
  1195. | 0x2E when !full_parsing ->
  1196. TMorphShape (parse_morph_shape ch len)
  1197. (* 0x2F invalid *)
  1198. | 0x30 when !full_parsing ->
  1199. TFont2 (parse_cid_data ch len)
  1200. (* 0x31-37 invalid *)
  1201. | 0x38 ->
  1202. let read_export() =
  1203. let cid = read_ui16 ch in
  1204. let name = read_string ch in
  1205. {
  1206. exp_id = cid;
  1207. exp_name = name
  1208. }
  1209. in
  1210. TExport (read_count (read_ui16 ch) read_export ())
  1211. | 0x39 ->
  1212. let url = read_string ch in
  1213. TImport (url, read_count (read_ui16 ch) parse_import ch)
  1214. (*// 0x3A TEnableDebugger *)
  1215. | 0x3B ->
  1216. let cid = read_ui16 ch in
  1217. let actions = parse_actions ch in
  1218. TDoInitAction {
  1219. dia_id = cid;
  1220. dia_actions = actions;
  1221. }
  1222. | 0x3C ->
  1223. TVideoStream (parse_cid_data ch len)
  1224. | 0x3D ->
  1225. TVideoFrame (parse_cid_data ch len)
  1226. | 0x3E ->
  1227. TFontInfo2 (parse_cid_data ch len)
  1228. | 0x3F ->
  1229. (* undocumented ? *)
  1230. TDebugID (nread_string ch len)
  1231. | 0x40 ->
  1232. let tag = read_ui16 ch in
  1233. (* 0 in general, 6517 for some swfs *)
  1234. let pass_md5 = read_string ch in
  1235. TEnableDebugger2 (tag,pass_md5)
  1236. | 0x41 ->
  1237. let recursion_depth = read_ui16 ch in
  1238. let script_timeout = read_ui16 ch in
  1239. TScriptLimits (recursion_depth, script_timeout)
  1240. (*// 0x42 TSetTabIndex *)
  1241. (* 0x43-0x44 invalid *)
  1242. | 0x45 ->
  1243. let flags = IO.read_i32 ch in
  1244. let mask = 1 lor 8 lor 16 lor 32 lor 64 in
  1245. if (flags lor mask) <> mask then failwith ("Invalid file attributes " ^ string_of_int flags);
  1246. TFilesAttributes {
  1247. fa_network = (flags land 1) <> 0;
  1248. (* flags 2,4 : reserved *)
  1249. fa_as3 = (flags land 8) <> 0;
  1250. fa_metadata = (flags land 16) <> 0;
  1251. fa_gpu = (flags land 32) <> 0;
  1252. fa_direct_blt = (flags land 64) <> 0;
  1253. }
  1254. | 0x46 when !full_parsing ->
  1255. TPlaceObject3 (parse_place_object ch true)
  1256. | 0x47 ->
  1257. let url = read_string ch in
  1258. if IO.read_byte ch <> 1 then assert false;
  1259. if IO.read_byte ch <> 0 then assert false;
  1260. TImport2 (url, read_count (read_ui16 ch) parse_import ch)
  1261. | 0x48 when !full_parsing || !force_as3_parsing ->
  1262. TActionScript3 (None , As3parse.parse ch len)
  1263. | 0x49 when !full_parsing ->
  1264. TFontAlignZones (parse_cid_data ch len)
  1265. | 0x4A ->
  1266. TCSMSettings (parse_cid_data ch len)
  1267. | 0x4B when !full_parsing ->
  1268. TFont3 (parse_cid_data ch len)
  1269. | 0x4C ->
  1270. let i = read_ui16 ch in
  1271. let rec loop i =
  1272. if i = 0 then
  1273. []
  1274. else
  1275. let a = read_ui16 ch in
  1276. let s = read_string ch in
  1277. {
  1278. f9_cid = if a = 0 then None else Some a;
  1279. f9_classname = s;
  1280. } :: loop (i - 1)
  1281. in
  1282. TF9Classes (loop i)
  1283. | 0x4D ->
  1284. TMetaData (read_string ch)
  1285. | 0x4E ->
  1286. let cid = read_ui16 ch in
  1287. let rect = read_rect ch in
  1288. TScale9 (cid,rect)
  1289. (* 0x4F-0x51 invalid *)
  1290. | 0x52 when !full_parsing || !force_as3_parsing ->
  1291. let id = read_i32 ch in
  1292. let frame = read_string ch in
  1293. let len = len - (4 + String.length frame + 1) in
  1294. TActionScript3 (Some (id,frame), As3parse.parse ch len)
  1295. | 0x53 when !full_parsing ->
  1296. TShape4 (parse_shape ch len 4)
  1297. | 0x54 when !full_parsing ->
  1298. TMorphShape2 (parse_morph_shape ch len)
  1299. (* 0x55 invalid *)
  1300. | 0x56 ->
  1301. let scenes = read_count (As3parse.read_int ch) (fun() ->
  1302. let offset = As3parse.read_int ch in
  1303. let name = read_string ch in
  1304. (offset, name)
  1305. ) () in
  1306. let frames = read_count (As3parse.read_int ch) (fun() ->
  1307. let f = As3parse.read_int ch in
  1308. let name = read_string ch in
  1309. (f, name)
  1310. ) () in
  1311. TScenes (scenes,frames)
  1312. | 0x57 ->
  1313. let cid = read_ui16 ch in
  1314. if read_i32 ch <> 0 then assert false;
  1315. let rec loop len =
  1316. if len > Sys.max_string_length then
  1317. let s = nread_string ch Sys.max_string_length in
  1318. s :: loop (len - Sys.max_string_length)
  1319. else
  1320. [nread_string ch len]
  1321. in
  1322. (match loop (len - 6) with
  1323. | [data] -> TBinaryData (cid,data)
  1324. | data -> TBigBinaryData (cid,data))
  1325. | 0x58 ->
  1326. TFontName (parse_cid_data ch len)
  1327. (* // 0x59 TStartSound2 *)
  1328. | 0x5A ->
  1329. let id = read_ui16 ch in
  1330. let size = read_i32 ch in
  1331. let deblock = read_ui16 ch in
  1332. let data = nread_string ch size in
  1333. let data, table = extract_jpg_table data in
  1334. let alpha = nread_string ch (len - 6 - size) in
  1335. TBitsJPEG4 {
  1336. bd_id = id;
  1337. bd_table = table;
  1338. bd_data = data;
  1339. bd_alpha = Some alpha;
  1340. bd_deblock = Some deblock;
  1341. }
  1342. | 0x5B ->
  1343. TFont4 (parse_cid_data ch len)
  1344. | _ ->
  1345. (*if !Swf.warnings then Printf.printf "Unknown tag 0x%.2X\n" id;*)
  1346. TUnknown (id,nread_string ch len)
  1347. ) in
  1348. (* let len2 = tag_data_length t in
  1349. if len <> len2 then error (Printf.sprintf "Datalen mismatch for tag 0x%.2X (%d != %d)" id len len2);
  1350. *) {
  1351. tid = gen_id();
  1352. tdata = t;
  1353. textended = extended;
  1354. }
  1355. and parse_tag_list ch =
  1356. let rec loop acc =
  1357. let h = (try read_ui16 ch with IO.No_more_input -> 0) in
  1358. match parse_tag ch h with
  1359. | { tdata = TEnd } -> List.rev acc
  1360. | t -> loop (t :: acc)
  1361. in
  1362. loop []
  1363. let parse ch =
  1364. let sign = nread_string ch 3 in
  1365. if sign <> "FWS" && sign <> "CWS" then error "Invalid SWF signature";
  1366. let ver = read_byte ch in
  1367. swf_version := ver;
  1368. ignore(read_i32 ch); (* file length *)
  1369. let compressed, ch = (if sign = "CWS" then true , inflate ch else false, ch) in
  1370. let size = read_rect ch in
  1371. let fps = read_ui16 ch in
  1372. let frame_count = read_ui16 ch in
  1373. let h = {
  1374. h_version = ver;
  1375. h_size = size;
  1376. h_fps = fps;
  1377. h_frame_count = frame_count;
  1378. h_compressed = compressed;
  1379. } in
  1380. let data = h , parse_tag_list ch in
  1381. if compressed then IO.close_in ch;
  1382. data
  1383. (* ************************************************************************ *)
  1384. (* WRITING *)
  1385. let rec tag_id = function
  1386. | TEnd -> 0x00
  1387. | TShowFrame -> 0x01
  1388. | TShape _ -> 0x02
  1389. | TRemoveObject _ -> 0x05
  1390. | TBitsJPEG _ -> 0x06
  1391. | TJPEGTables _ -> 0x08
  1392. | TSetBgColor _ -> 0x09
  1393. | TFont _ -> 0x0A
  1394. | TText _ -> 0x0B
  1395. | TDoAction _ -> 0x0C
  1396. | TFontInfo _ -> 0x0D
  1397. | TSound _ -> 0x0E
  1398. | TStartSound _ -> 0x0F
  1399. | TBitsLossless _ -> 0x14
  1400. | TBitsJPEG2 _ -> 0x15
  1401. | TShape2 _ -> 0x16
  1402. | TProtect -> 0x18
  1403. | TPlaceObject2 _ -> 0x1A
  1404. | TRemoveObject2 _ -> 0x1C
  1405. | TShape3 _ -> 0x20
  1406. | TText2 _ -> 0x21
  1407. | TButton2 _ -> 0x22
  1408. | TBitsJPEG3 _ -> 0x23
  1409. | TBitsLossless2 _ -> 0x24
  1410. | TEditText _ -> 0x25
  1411. | TClip _ -> 0x27
  1412. | TProductInfo _ -> 0x29
  1413. | TFrameLabel _ -> 0x2B
  1414. | TSoundStreamHead2 _ -> 0x2D
  1415. | TMorphShape _ -> 0x2E
  1416. | TFont2 _ -> 0x30
  1417. | TExport _ -> 0x38
  1418. | TImport _ -> 0x39
  1419. | TDoInitAction _ -> 0x3B
  1420. | TVideoStream _ -> 0x3C
  1421. | TVideoFrame _ -> 0x3D
  1422. | TFontInfo2 _ -> 0x3E
  1423. | TDebugID _ -> 0x3F
  1424. | TEnableDebugger2 _ -> 0x40
  1425. | TScriptLimits _ -> 0x41
  1426. | TFilesAttributes _ -> 0x45
  1427. | TPlaceObject3 _ -> 0x46
  1428. | TImport2 _ -> 0x47
  1429. | TFontAlignZones _ -> 0x49
  1430. | TCSMSettings _ -> 0x4A
  1431. | TFont3 _ -> 0x4B
  1432. | TF9Classes _ -> 0x4C
  1433. | TMetaData _ -> 0x4D
  1434. | TScale9 _ -> 0x4E
  1435. | TActionScript3 (None,_) -> 0x48
  1436. | TActionScript3 _ -> 0x52
  1437. | TShape4 _ -> 0x53
  1438. | TMorphShape2 _ -> 0x54
  1439. | TScenes _ -> 0x56
  1440. | TBinaryData _ | TBigBinaryData _ -> 0x57
  1441. | TFontName _ -> 0x58
  1442. | TBitsJPEG4 _ -> 0x5A
  1443. | TFont4 _ -> 0x5B
  1444. | TUnknown (id,_) -> id
  1445. let write_clip_event ch c =
  1446. write_event ch c.cle_events;
  1447. write_i32 ch (actions_length c.cle_actions + opt_len (const 1) c.cle_key);
  1448. opt (write ch) c.cle_key;
  1449. write_actions ch c.cle_actions
  1450. let write_clip_events ch event_list =
  1451. write_ui16 ch 0;
  1452. let all_events = List.fold_left (fun acc c -> acc lor c.cle_events) 0 event_list in
  1453. write_event ch all_events;
  1454. List.iter (write_clip_event ch) event_list;
  1455. write_event ch 0
  1456. let write_shape_fill_style ch s =
  1457. match s with
  1458. | SFSSolid c ->
  1459. write_byte ch 0x00;
  1460. write_rgb ch c
  1461. | SFSSolid3 c ->
  1462. write_byte ch 0x00;
  1463. write_rgba ch c
  1464. | SFSLinearGradient (m,g) ->
  1465. write_byte ch 0x10;
  1466. write_matrix ch m;
  1467. write_gradient ch g
  1468. | SFSRadialGradient (m,g,None) ->
  1469. write_byte ch 0x12;
  1470. write_matrix ch m;
  1471. write_gradient ch g
  1472. | SFSRadialGradient (m,g,Some i) ->
  1473. write_byte ch 0x13;
  1474. write_matrix ch m;
  1475. write_gradient ch g;
  1476. write_i16 ch i;
  1477. | SFSBitmap b ->
  1478. write_byte ch (match b.sfb_repeat , b.sfb_smooth with
  1479. | true, false -> 0x40
  1480. | false , false -> 0x41
  1481. | true , true -> 0x42
  1482. | false, true -> 0x43);
  1483. write_ui16 ch b.sfb_cid;
  1484. write_matrix ch b.sfb_mpos
  1485. let write_shape_line_style ch l =
  1486. write_ui16 ch l.sls_width;
  1487. opt (write_ui16 ch) l.sls_flags;
  1488. opt (write_ui16 ch) l.sls_miter;
  1489. match l.sls_fill with
  1490. | None ->
  1491. write_color ch l.sls_color;
  1492. | Some fill ->
  1493. write_shape_fill_style ch fill
  1494. let write_shape_array ch f sl =
  1495. let n = List.length sl in
  1496. if n >= 0xFF then begin
  1497. write_byte ch 0xFF;
  1498. write_ui16 ch n;
  1499. end else
  1500. write_byte ch n;
  1501. List.iter (f ch) sl
  1502. let write_shape_style_change_record ch b nlbits nfbits s =
  1503. let flags = make_flags [flag s.scsr_move; flag s.scsr_fs0; flag s.scsr_fs1; flag s.scsr_ls; flag s.scsr_new_styles] in
  1504. write_bits b 6 flags;
  1505. opt (fun (n,dx,dy) ->
  1506. write_bits b 5 n;
  1507. write_bits b n dx;
  1508. write_bits b n dy;
  1509. ) s.scsr_move;
  1510. opt (write_bits b ~nbits:!nfbits) s.scsr_fs0;
  1511. opt (write_bits b ~nbits:!nfbits) s.scsr_fs1;
  1512. opt (write_bits b ~nbits:!nlbits) s.scsr_ls;
  1513. match s.scsr_new_styles with
  1514. | None -> ()
  1515. | Some s ->
  1516. flush_bits b;
  1517. write_shape_array ch write_shape_fill_style s.sns_fill_styles;
  1518. write_shape_array ch write_shape_line_style s.sns_line_styles;
  1519. nfbits := s.sns_nfbits;
  1520. nlbits := s.sns_nlbits;
  1521. write_bits b 4 !nfbits;
  1522. write_bits b 4 !nlbits
  1523. let write_shape_record ch b nlbits nfbits = function
  1524. | SRStyleChange s ->
  1525. write_shape_style_change_record ch b nlbits nfbits s
  1526. | SRCurvedEdge s ->
  1527. write_bits b 2 2;
  1528. write_bits b 4 (s.scer_nbits - 2);
  1529. write_bits b s.scer_nbits s.scer_cx;
  1530. write_bits b s.scer_nbits s.scer_cy;
  1531. write_bits b s.scer_nbits s.scer_ax;
  1532. write_bits b s.scer_nbits s.scer_ay;
  1533. | SRStraightEdge s ->
  1534. write_bits b 2 3;
  1535. write_bits b 4 (s.sser_nbits - 2);
  1536. match s.sser_line with
  1537. | None , None -> assert false
  1538. | None , Some p
  1539. | Some p , None ->
  1540. write_bits b 1 0;
  1541. write_bits b 1 (if (fst s.sser_line) = None then 1 else 0);
  1542. write_bits b s.sser_nbits p;
  1543. | Some dx, Some dy ->
  1544. write_bits b 1 1;
  1545. write_bits b s.sser_nbits dx;
  1546. write_bits b s.sser_nbits dy
  1547. let write_shape_without_style ch s =
  1548. (* write_shape_array ch write_shape_fill_style s.sws_fill_styles; *)
  1549. (* write_shape_array ch write_shape_line_style s.sws_line_styles; *)
  1550. let r = s in (* s.sws_records in *)
  1551. let b = output_bits ch in
  1552. write_bits b 4 r.srs_nfbits;
  1553. write_bits b 4 r.srs_nlbits;
  1554. let nlbits = ref r.srs_nlbits in
  1555. let nfbits = ref r.srs_nfbits in
  1556. List.iter (write_shape_record ch b nlbits nfbits) r.srs_records;
  1557. (* write_bits b 6 0; *)
  1558. flush_bits b
  1559. let write_shape_with_style ch s =
  1560. write_shape_array ch write_shape_fill_style s.sws_fill_styles;
  1561. write_shape_array ch write_shape_line_style s.sws_line_styles;
  1562. let r = s.sws_records in
  1563. let b = output_bits ch in
  1564. write_bits b 4 r.srs_nfbits;
  1565. write_bits b 4 r.srs_nlbits;
  1566. let nlbits = ref r.srs_nlbits in
  1567. let nfbits = ref r.srs_nfbits in
  1568. List.iter (write_shape_record ch b nlbits nfbits) r.srs_records;
  1569. write_bits b 6 0;
  1570. flush_bits b
  1571. let write_shape ch s =
  1572. write_ui16 ch s.sh_id;
  1573. write_rect ch s.sh_bounds;
  1574. (match s.sh_bounds2 with
  1575. | None -> ()
  1576. | Some (r,b) ->
  1577. write_rect ch r;
  1578. write_byte ch b);
  1579. write_shape_with_style ch s.sh_style
  1580. let write_bitmap_lossless ch b =
  1581. write_ui16 ch b.bll_id;
  1582. write_byte ch b.bll_format;
  1583. write_ui16 ch b.bll_width;
  1584. write_ui16 ch b.bll_height;
  1585. nwrite_string ch b.bll_data
  1586. let write_morph_shape ch s =
  1587. write_ui16 ch s.msh_id;
  1588. write_rect ch s.msh_start_bounds;
  1589. write_rect ch s.msh_end_bounds;
  1590. nwrite_string ch s.msh_data
  1591. let write_text_record ch t r =
  1592. write_byte ch (make_flags [flag r.txr_dx; flag r.txr_dy; flag r.txr_color; flag r.txr_font; false; false; false; true]);
  1593. opt (fun (id,_) -> write_ui16 ch id) r.txr_font;
  1594. opt (write_color ch) r.txr_color;
  1595. opt (write_i16 ch) r.txr_dx;
  1596. opt (write_i16 ch) r.txr_dy;
  1597. opt (fun (_,id) -> write_ui16 ch id) r.txr_font;
  1598. write_byte ch (List.length r.txr_glyphs);
  1599. let bits = output_bits ch in
  1600. List.iter (fun g ->
  1601. write_bits bits t.txt_ngbits g.txg_index;
  1602. write_bits bits t.txt_nabits g.txg_advanced;
  1603. ) r.txr_glyphs;
  1604. flush_bits bits
  1605. let write_text ch t =
  1606. write_ui16 ch t.txt_id;
  1607. write_big_rect ch t.txt_bounds;
  1608. write_matrix ch t.txt_matrix;
  1609. write_byte ch t.txt_ngbits;
  1610. write_byte ch t.txt_nabits;
  1611. List.iter (write_text_record ch t) t.txt_records;
  1612. write_byte ch 0
  1613. let write_edit_text_layout ch l =
  1614. write_byte ch l.edtl_align;
  1615. write_ui16 ch l.edtl_left_margin;
  1616. write_ui16 ch l.edtl_right_margin;
  1617. write_ui16 ch l.edtl_indent;
  1618. write_ui16 ch l.edtl_leading
  1619. let write_edit_text ch t =
  1620. write_ui16 ch t.edt_id;
  1621. write_rect ch t.edt_bounds;
  1622. write_ui16 ch (make_flags [
  1623. flag t.edt_font; flag t.edt_maxlen; flag t.edt_color; t.edt_readonly;
  1624. t.edt_password; t.edt_multiline; t.edt_wordwrap; flag t.edt_text;
  1625. t.edt_outlines; t.edt_html; false; t.edt_border;
  1626. t.edt_noselect; flag t.edt_layout; t.edt_autosize; false
  1627. ]);
  1628. opt (fun (id,h) -> write_ui16 ch id; write_ui16 ch h) t.edt_font;
  1629. opt (write_rgba ch) t.edt_color;
  1630. opt (write_ui16 ch) t.edt_maxlen;
  1631. opt (write_edit_text_layout ch) t.edt_layout;
  1632. write_string ch t.edt_variable;
  1633. opt (write_string ch) t.edt_text
  1634. let write_cid_data ch c =
  1635. write_ui16 ch c.cd_id;
  1636. nwrite_string ch c.cd_data
  1637. let write_filter_gradient ch fg =
  1638. write_byte ch (List.length fg.fgr_colors);
  1639. List.iter (fun (c,_) -> write_rgba ch c) fg.fgr_colors;
  1640. List.iter (fun (_,n) -> write_byte ch n) fg.fgr_colors;
  1641. nwrite_string ch fg.fgr_data
  1642. let write_filter ch = function
  1643. | FDropShadow s ->
  1644. write_byte ch 0;
  1645. nwrite_string ch s
  1646. | FBlur s ->
  1647. write_byte ch 1;
  1648. nwrite_string ch s
  1649. | FGlow s ->
  1650. write_byte ch 2;
  1651. nwrite_string ch s
  1652. | FBevel s ->
  1653. write_byte ch 3;
  1654. nwrite_string ch s
  1655. | FGradientGlow fg ->
  1656. write_byte ch 4;
  1657. write_filter_gradient ch fg
  1658. | FAdjustColor s ->
  1659. write_byte ch 6;
  1660. nwrite_string ch s
  1661. | FGradientBevel fg ->
  1662. write_byte ch 7;
  1663. write_filter_gradient ch fg
  1664. let write_button_record ch r =
  1665. write_byte ch r.btr_flags;
  1666. write_ui16 ch r.btr_cid;
  1667. write_ui16 ch r.btr_depth;
  1668. write_matrix ch r.btr_mpos;
  1669. (match r.btr_color with
  1670. | None -> ()
  1671. | Some c ->
  1672. write_cxa ch c);
  1673. opt (fun l ->
  1674. write_byte ch (List.length l);
  1675. List.iter (write_filter ch) l
  1676. ) r.btr_filters;
  1677. (match r.btr_blendmode with
  1678. | None -> ()
  1679. | Some c ->
  1680. write_byte ch c)
  1681. let rec write_button_actions ch = function
  1682. | [] -> assert false
  1683. | [a] ->
  1684. write_ui16 ch 0;
  1685. write_ui16 ch a.bta_flags;
  1686. write_actions ch a.bta_actions
  1687. | a :: l ->
  1688. let size = button_action_length a in
  1689. write_ui16 ch size;
  1690. write_ui16 ch a.bta_flags;
  1691. write_actions ch a.bta_actions;
  1692. write_button_actions ch l
  1693. let write_button2 ch b =
  1694. write_ui16 ch b.bt2_id;
  1695. write_byte ch (if b.bt2_track_as_menu then 1 else 0);
  1696. if b.bt2_actions <> [] then write_ui16 ch (3 + sum button_record_length b.bt2_records) else write_ui16 ch 0;
  1697. List.iter (write_button_record ch) b.bt2_records;
  1698. write_byte ch 0;
  1699. if b.bt2_actions <> [] then write_button_actions ch b.bt2_actions
  1700. let write_place_object ch p v3 =
  1701. write_byte ch (make_flags [
  1702. p.po_move;
  1703. flag p.po_cid;
  1704. flag p.po_matrix;
  1705. flag p.po_color;
  1706. flag p.po_ratio;
  1707. flag p.po_inst_name;
  1708. flag p.po_clip_depth;
  1709. flag p.po_events
  1710. ]);
  1711. if v3 then write_byte ch (make_flags [flag p.po_filters; flag p.po_blend; flag p.po_bcache]);
  1712. write_ui16 ch p.po_depth;
  1713. opt (write_ui16 ch) p.po_cid;
  1714. opt (write_matrix ch) p.po_matrix;
  1715. opt (write_cxa ch) p.po_color;
  1716. opt (write_ui16 ch) p.po_ratio;
  1717. opt (write_string ch) p.po_inst_name;
  1718. opt (write_ui16 ch) p.po_clip_depth;
  1719. opt (write_clip_events ch) p.po_events;
  1720. if v3 then begin
  1721. opt (fun l ->
  1722. write_byte ch (List.length l);
  1723. List.iter (write_filter ch) l
  1724. ) p.po_filters;
  1725. opt (write_byte ch) p.po_blend;
  1726. opt (write_byte ch) p.po_bcache;
  1727. end
  1728. let rec write_tag_data ch = function
  1729. | TEnd ->
  1730. ()
  1731. | TShowFrame ->
  1732. ()
  1733. | TShape s ->
  1734. write_shape ch s
  1735. | TRemoveObject r ->
  1736. write_ui16 ch r.rmo_id;
  1737. write_ui16 ch r.rmo_depth;
  1738. | TBitsJPEG b ->
  1739. write_ui16 ch b.jpg_id;
  1740. nwrite_string ch b.jpg_data
  1741. | TJPEGTables tab ->
  1742. nwrite_string ch tab
  1743. | TSetBgColor c ->
  1744. write_rgb ch c
  1745. | TFont c ->
  1746. write_cid_data ch c
  1747. | TText t ->
  1748. write_text ch t
  1749. | TDoAction acts ->
  1750. write_actions ch acts
  1751. | TFontInfo c ->
  1752. write_cid_data ch c
  1753. | TSound s ->
  1754. write_ui16 ch s.so_id;
  1755. write_byte ch s.so_flags;
  1756. write_i32 ch s.so_samples;
  1757. nwrite_string ch s.so_data
  1758. | TStartSound s ->
  1759. write_ui16 ch s.sts_id;
  1760. nwrite_string ch s.sts_data
  1761. | TBitsLossless b ->
  1762. write_bitmap_lossless ch b
  1763. | TBitsJPEG2 b ->
  1764. write_ui16 ch b.bd_id;
  1765. opt (nwrite_string ch) b.bd_table;
  1766. nwrite_string ch b.bd_data;
  1767. | TShape2 s ->
  1768. write_shape ch s
  1769. | TProtect ->
  1770. ()
  1771. | TPlaceObject2 p ->
  1772. write_place_object ch p false;
  1773. | TRemoveObject2 depth ->
  1774. write_ui16 ch depth;
  1775. | TShape3 s ->
  1776. write_shape ch s
  1777. | TText2 t ->
  1778. write_text ch t
  1779. | TButton2 b ->
  1780. write_button2 ch b
  1781. | TBitsJPEG3 b ->
  1782. write_ui16 ch b.bd_id;
  1783. write_i32 ch (String.length b.bd_data + opt_len String.length b.bd_table);
  1784. opt (nwrite_string ch) b.bd_table;
  1785. nwrite_string ch b.bd_data;
  1786. opt (nwrite_string ch) b.bd_alpha;
  1787. | TBitsLossless2 b ->
  1788. write_bitmap_lossless ch b
  1789. | TEditText t ->
  1790. write_edit_text ch t
  1791. | TClip c ->
  1792. write_ui16 ch c.c_id;
  1793. write_ui16 ch c.c_frame_count;
  1794. List.iter (write_tag ch) c.c_tags;
  1795. write_tag ch tag_end;
  1796. | TProductInfo s ->
  1797. nwrite_string ch s
  1798. | TFrameLabel (label,id) ->
  1799. write_string ch label;
  1800. opt (write ch) id;
  1801. | TSoundStreamHead2 data ->
  1802. nwrite_string ch data
  1803. | TMorphShape s ->
  1804. write_morph_shape ch s
  1805. | TFont2 c ->
  1806. write_cid_data ch c
  1807. | TExport el ->
  1808. write_ui16 ch (List.length el);
  1809. List.iter (fun e ->
  1810. write_ui16 ch e.exp_id;
  1811. write_string ch e.exp_name
  1812. ) el
  1813. | TImport (url,il) ->
  1814. write_string ch url;
  1815. write_ui16 ch (List.length il);
  1816. List.iter (fun i ->
  1817. write_ui16 ch i.imp_id;
  1818. write_string ch i.imp_name
  1819. ) il
  1820. | TDoInitAction i ->
  1821. write_ui16 ch i.dia_id;
  1822. write_actions ch i.dia_actions;
  1823. | TVideoStream c ->
  1824. write_cid_data ch c
  1825. | TVideoFrame c ->
  1826. write_cid_data ch c
  1827. | TFontInfo2 c ->
  1828. write_cid_data ch c
  1829. | TDebugID s ->
  1830. nwrite_string ch s
  1831. | TEnableDebugger2 (tag,pass) ->
  1832. write_ui16 ch tag;
  1833. write_string ch pass
  1834. | TScriptLimits (recursion_depth, script_timeout) ->
  1835. write_ui16 ch recursion_depth;
  1836. write_ui16 ch script_timeout;
  1837. | TFilesAttributes f ->
  1838. let flags = make_flags [f.fa_network;false;false;f.fa_as3;f.fa_metadata;f.fa_gpu;f.fa_direct_blt] in
  1839. write_i32 ch flags
  1840. | TPlaceObject3 p ->
  1841. write_place_object ch p true;
  1842. | TImport2 (url,il) ->
  1843. write_string ch url;
  1844. write_byte ch 1;
  1845. write_byte ch 0;
  1846. write_ui16 ch (List.length il);
  1847. List.iter (fun i ->
  1848. write_ui16 ch i.imp_id;
  1849. write_string ch i.imp_name
  1850. ) il
  1851. | TFontAlignZones c ->
  1852. write_cid_data ch c
  1853. | TCSMSettings c ->
  1854. write_cid_data ch c
  1855. | TFont3 c ->
  1856. write_cid_data ch c
  1857. | TF9Classes l ->
  1858. write_ui16 ch (List.length l);
  1859. List.iter (fun c ->
  1860. write_ui16 ch (match c.f9_cid with None -> 0 | Some id -> id);
  1861. write_string ch c.f9_classname
  1862. ) l
  1863. | TMetaData meta ->
  1864. write_string ch meta
  1865. | TScale9 (cid,r) ->
  1866. write_ui16 ch cid;
  1867. write_rect ch r;
  1868. | TActionScript3 (id,a) ->
  1869. (match id with
  1870. | None -> ()
  1871. | Some (id,frame) ->
  1872. write_i32 ch id;
  1873. write_string ch frame;
  1874. );
  1875. As3parse.write ch a
  1876. | TShape4 s ->
  1877. write_shape ch s
  1878. | TMorphShape2 m ->
  1879. write_morph_shape ch m
  1880. | TScenes (sl,fl) ->
  1881. As3parse.write_int ch (List.length sl);
  1882. List.iter (fun (n,s) ->
  1883. As3parse.write_int ch n;
  1884. write_string ch s;
  1885. ) sl;
  1886. As3parse.write_int ch (List.length fl);
  1887. List.iter (fun (n,s) ->
  1888. As3parse.write_int ch n;
  1889. write_string ch s;
  1890. ) fl;
  1891. | TBinaryData (id,data) ->
  1892. write_ui16 ch id;
  1893. write_i32 ch 0;
  1894. nwrite_string ch data
  1895. | TBigBinaryData (id,data) ->
  1896. write_ui16 ch id;
  1897. write_i32 ch 0;
  1898. List.iter (nwrite_string ch) data
  1899. | TFontName c ->
  1900. write_cid_data ch c
  1901. | TBitsJPEG4 b ->
  1902. write_ui16 ch b.bd_id;
  1903. write_i32 ch (String.length b.bd_data + opt_len String.length b.bd_table);
  1904. opt (write_ui16 ch) b.bd_deblock;
  1905. opt (nwrite_string ch) b.bd_table;
  1906. nwrite_string ch b.bd_data;
  1907. opt (nwrite_string ch) b.bd_alpha;
  1908. | TFont4 c ->
  1909. write_cid_data ch c
  1910. | TUnknown (_,data) ->
  1911. nwrite_string ch data
  1912. and write_tag ch t =
  1913. let id = tag_id t.tdata in
  1914. let dlen = tag_data_length t.tdata in
  1915. if t.textended || dlen >= 63 then begin
  1916. write_ui16 ch ((id lsl 6) lor 63);
  1917. write_i32 ch dlen;
  1918. end else begin
  1919. write_ui16 ch ((id lsl 6) lor dlen);
  1920. end;
  1921. write_tag_data ch t.tdata
  1922. let write ch (h,tags) =
  1923. swf_version := h.h_version;
  1924. nwrite_string ch (if h.h_compressed then "CWS" else "FWS");
  1925. write ch (char_of_int h.h_version);
  1926. let rec calc_len = function
  1927. | [] -> tag_length tag_end
  1928. | t :: l ->
  1929. tag_length t + calc_len l
  1930. in
  1931. let len = calc_len tags in
  1932. let len = len + 4 + 4 + rect_length h.h_size + 2 + 2 in
  1933. write_i32 ch len;
  1934. let ch = (if h.h_compressed then deflate ch else ch) in
  1935. write_rect ch h.h_size;
  1936. write_ui16 ch h.h_fps;
  1937. write_ui16 ch h.h_frame_count;
  1938. List.iter (write_tag ch) tags;
  1939. write_tag ch tag_end;
  1940. if h.h_compressed then IO.close_out ch
  1941. (* ************************************************************************ *)
  1942. (* EXTRA *)
  1943. let scan fid f t =
  1944. match t.tdata with
  1945. | TEnd
  1946. | TShowFrame
  1947. | TJPEGTables _
  1948. | TSetBgColor _
  1949. | TDoAction _
  1950. | TActionScript3 _
  1951. | TProtect
  1952. | TRemoveObject2 _
  1953. | TFrameLabel _
  1954. | TSoundStreamHead2 _
  1955. | TScenes _
  1956. | TEnableDebugger2 _
  1957. | TMetaData _
  1958. | TScriptLimits _
  1959. | TDebugID _
  1960. | TFilesAttributes _
  1961. | TProductInfo _
  1962. -> ()
  1963. | TF9Classes l ->
  1964. List.iter (fun c ->
  1965. match c.f9_cid with
  1966. | None -> ()
  1967. | Some id -> c.f9_cid <- Some (f id)
  1968. ) l
  1969. | TShape s
  1970. | TShape2 s
  1971. | TShape3 s
  1972. | TShape4 s ->
  1973. s.sh_id <- fid s.sh_id;
  1974. let loop fs =
  1975. List.iter (fun s -> match s with
  1976. | SFSBitmap b ->
  1977. if b.sfb_cid <> 0xFFFF then b.sfb_cid <- f b.sfb_cid;
  1978. | _ ->
  1979. ()
  1980. ) fs
  1981. in
  1982. loop s.sh_style.sws_fill_styles;
  1983. List.iter (fun s -> match s with
  1984. | SRStyleChange { scsr_new_styles = Some s } ->
  1985. loop s.sns_fill_styles
  1986. | _ ->
  1987. ()
  1988. ) s.sh_style.sws_records.srs_records;
  1989. | TRemoveObject r ->
  1990. r.rmo_id <- f r.rmo_id
  1991. | TBitsJPEG b ->
  1992. b.jpg_id <- fid b.jpg_id
  1993. | TBitsJPEG2 b ->
  1994. b.bd_id <- fid b.bd_id
  1995. | TText t
  1996. | TText2 t ->
  1997. t.txt_id <- fid t.txt_id;
  1998. List.iter (fun r -> match r.txr_font with None -> () | Some (id,id2) -> r.txr_font <- Some (f id,id2)) t.txt_records
  1999. | TEditText t ->
  2000. t.edt_id <- fid t.edt_id;
  2001. (match t.edt_font with None -> () | Some (id,h) -> t.edt_font <- Some (f id,h))
  2002. | TSound s ->
  2003. s.so_id <- fid s.so_id
  2004. | TStartSound s ->
  2005. s.sts_id <- f s.sts_id
  2006. | TBitsLossless b
  2007. | TBitsLossless2 b ->
  2008. b.bll_id <- fid b.bll_id
  2009. | TPlaceObject2 p ->
  2010. p.po_cid <- (match p.po_cid with None -> None | Some id -> Some (f id))
  2011. | TButton2 b ->
  2012. b.bt2_id <- fid b.bt2_id;
  2013. List.iter (fun r ->
  2014. r.btr_cid <- f r.btr_cid
  2015. ) b.bt2_records;
  2016. | TBitsJPEG3 j ->
  2017. j.bd_id <- fid j.bd_id
  2018. | TClip c ->
  2019. c.c_id <- fid c.c_id
  2020. | TMorphShape s | TMorphShape2 s ->
  2021. s.msh_id <- fid s.msh_id
  2022. | TFont c | TFont2 c | TFont3 c | TFont4 c ->
  2023. c.cd_id <- fid c.cd_id
  2024. | TExport el ->
  2025. List.iter (fun e -> e.exp_id <- f e.exp_id) el
  2026. | TImport (_,il) | TImport2 (_,il) ->
  2027. List.iter (fun i -> i.imp_id <- fid i.imp_id) il
  2028. | TDoInitAction a ->
  2029. a.dia_id <- f a.dia_id
  2030. | TVideoStream c ->
  2031. c.cd_id <- fid c.cd_id
  2032. | TVideoFrame c ->
  2033. c.cd_id <- f c.cd_id
  2034. | TPlaceObject3 p ->
  2035. p.po_cid <- (match p.po_cid with None -> None | Some id -> Some (f id))
  2036. | TCSMSettings c ->
  2037. c.cd_id <- f c.cd_id
  2038. | TBinaryData (id,data) ->
  2039. t.tdata <- TBinaryData (fid id,data)
  2040. | TBigBinaryData (id,data) ->
  2041. t.tdata <- TBigBinaryData (fid id,data)
  2042. | TFontAlignZones c | TFontInfo c | TFontInfo2 c | TFontName c ->
  2043. c.cd_id <- f c.cd_id
  2044. | TScale9 (id,r) ->
  2045. t.tdata <- TScale9 (f id,r)
  2046. | TBitsJPEG4 j ->
  2047. j.bd_id <- fid j.bd_id
  2048. | TUnknown _ ->
  2049. ()
  2050. let tag_name = function
  2051. | TEnd -> "End"
  2052. | TShowFrame -> "ShowFrame"
  2053. | TShape _ -> "Shape"
  2054. | TRemoveObject _ -> "RemoveObject"
  2055. | TBitsJPEG _ -> "BitsJPEG"
  2056. | TJPEGTables _ -> "JPGETables"
  2057. | TSetBgColor _ -> "SetBgColor"
  2058. | TFont _ -> "Font"
  2059. | TText _ -> "Text"
  2060. | TDoAction _ -> "DoAction"
  2061. | TFontInfo _ -> "FontInfo"
  2062. | TSound _ -> "Sound"
  2063. | TStartSound _ -> "StartSound"
  2064. | TBitsLossless _ -> "BitsLossless"
  2065. | TBitsJPEG2 _ -> "BitsJPEG2"
  2066. | TShape2 _ -> "Shape2"
  2067. | TProtect -> "Protect"
  2068. | TPlaceObject2 _ -> "PlaceObject2"
  2069. | TRemoveObject2 _ -> "RemoveObject2"
  2070. | TShape3 _ -> "Shape3"
  2071. | TText2 _ -> "Text2"
  2072. | TButton2 _ -> "Button2"
  2073. | TBitsJPEG3 _ -> "BitsJPEG3"
  2074. | TBitsLossless2 _ -> "Lossless2"
  2075. | TEditText _ -> "EditText"
  2076. | TClip _ -> "Clip"
  2077. | TProductInfo _ -> "ProductInfo"
  2078. | TFrameLabel _ -> "FrameLabel"
  2079. | TSoundStreamHead2 _ -> "SoundStreamHead2"
  2080. | TMorphShape _ -> "MorphShape"
  2081. | TFont2 _ -> "Font2"
  2082. | TExport _ -> "Export"
  2083. | TImport _ -> "Import"
  2084. | TDoInitAction _ -> "DoInitAction"
  2085. | TVideoStream _ -> "VideoStream"
  2086. | TVideoFrame _ -> "VideoFrame"
  2087. | TFontInfo2 _ -> "FontInfo2"
  2088. | TDebugID _ -> "DebugID"
  2089. | TEnableDebugger2 _ -> "EnableDebugger2"
  2090. | TScriptLimits _ -> "ScriptLimits"
  2091. | TFilesAttributes _ -> "FilesAttributes"
  2092. | TPlaceObject3 _ -> "PlaceObject3"
  2093. | TImport2 _ -> "Import2"
  2094. | TFontAlignZones _ -> "FontAlignZones"
  2095. | TCSMSettings _ -> "TCSMSettings"
  2096. | TFont3 _ -> "Font3"
  2097. | TF9Classes _ -> "F9Classes"
  2098. | TMetaData _ -> "MetaData"
  2099. | TScale9 _ -> "Scale9"
  2100. | TActionScript3 _ -> "ActionScript3"
  2101. | TShape4 _ -> "Shape4"
  2102. | TMorphShape2 _ -> "MorphShape2"
  2103. | TScenes _ -> "Scenes"
  2104. | TBinaryData _ -> "BinaryData"
  2105. | TBigBinaryData _ -> "BigBinaryData"
  2106. | TFontName _ -> "FontName"
  2107. | TBitsJPEG4 _ -> "BitsJPEG4"
  2108. | TFont4 _ -> "Font4"
  2109. | TUnknown (n,_) -> Printf.sprintf "Unknown 0x%.2X" n
  2110. let init inflate deflate =
  2111. Swf.__parser := parse;
  2112. Swf.__printer := write;
  2113. Swf.__inflate := inflate;
  2114. Swf.__deflate := deflate;
  2115. ;;
  2116. Swf.__parser := parse;
  2117. Swf.__printer := write