Fix include style
[bcusdk.git] / common / image.cpp
blobcb331d644daf0b8a222ac969f93b87f7692da19f
1 /*
2 BCU SDK bcu development enviroment
3 Copyright (C) 2005-2010 Martin Koegler <mkoegler@auto.tuwien.ac.at>
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.
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.
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.
20 #include <assert.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include "loadctl.h"
24 #include "image.h"
26 String
27 HexDump (CArray data)
29 char buf[200];
30 String s;
31 int i;
32 sprintf (buf, "%04X ", 0);
33 s = buf;
34 for (i = 0; i < data (); i++)
36 sprintf (buf, "%02x ", data[i]);
37 s += buf;
38 if (i % 16 == 15)
40 sprintf (buf, "\n%04X ", i + 1);
41 s += buf;
44 s += "\n";
45 return s;
48 STR_Stream *
49 STR_Stream::fromArray (const CArray & c)
51 assert (c () >= 4);
52 assert (((c[0] << 8) | c[1]) + 2 == c ());
53 STR_Stream *i;
55 switch (c[2] << 8 | c[3])
57 case L_STRING_PAR:
58 i = new STR_StringParameter ();
59 break;
60 case L_INT_PAR:
61 i = new STR_IntParameter ();
62 break;
63 case L_FLOAT_PAR:
64 i = new STR_FloatParameter ();
65 break;
66 case L_LIST_PAR:
67 i = new STR_ListParameter ();
68 break;
69 case L_GROUP_OBJECT:
70 i = new STR_GroupObject ();
71 break;
72 case L_BCU_TYPE:
73 i = new STR_BCUType ();
74 break;
75 case L_BCU2_INIT:
76 i = new STR_BCU2Start ();
77 break;
78 case L_CODE:
79 i = new STR_Code ();
80 break;
81 case L_BCU1_SIZE:
82 i = new STR_BCU1Size ();
83 break;
84 case L_BCU2_SIZE:
85 i = new STR_BCU2Size ();
86 break;
87 case L_BCU2_KEY:
88 i = new STR_BCU2Key ();
89 break;
90 default:
91 i = new STR_Unknown ();
92 break;
94 if (i->init (c))
95 return i;
96 delete i;
97 i = new STR_Invalid ();
98 i->init (c);
99 return i;
102 STR_Invalid::STR_Invalid ()
106 bool
107 STR_Invalid::init (const CArray & c)
109 data = c;
110 return true;
113 CArray
114 STR_Invalid::toArray ()
116 return data;
119 String
120 STR_Invalid::decode ()
122 char buf[200];
123 String s;
124 sprintf (buf, "Invalid:\n");
125 s = buf;
126 return s + HexDump (data);
130 STR_Unknown::STR_Unknown ()
132 type = 0;
135 bool
136 STR_Unknown::init (const CArray & c)
138 data.set (c.array () + 4, c () - 4);
139 type = c[2] << 8 | c[3];
140 return true;
143 CArray
144 STR_Unknown::toArray ()
146 CArray d;
147 uint16_t len = 2 + data ();
148 d.resize (2 + len);
149 d[0] = (len >> 8) & 0xff;
150 d[1] = (len) & 0xff;
151 d[2] = (type >> 8) & 0xff;
152 d[3] = (type) & 0xff;
153 d.setpart (data, 4);
154 return d;
157 String
158 STR_Unknown::decode ()
160 char buf[200];
161 String s;
162 sprintf (buf, "Unknown %04x:\n", type);
163 s = buf;
164 return s + HexDump (data);
167 STR_BCUType::STR_BCUType ()
169 bcutype = 0;
172 bool
173 STR_BCUType::init (const CArray & c)
175 if (c () != 6)
176 return false;
177 bcutype = c[4] << 8 | c[5];
178 return true;
181 CArray
182 STR_BCUType::toArray ()
184 CArray d;
185 uint16_t len = 4;
186 d.resize (2 + len);
187 d[0] = (len >> 8) & 0xff;
188 d[1] = (len) & 0xff;
189 d[2] = (L_BCU_TYPE >> 8) & 0xff;
190 d[3] = (L_BCU_TYPE) & 0xff;
191 d[4] = (bcutype >> 8) & 0xff;
192 d[5] = (bcutype) & 0xff;
193 return d;
196 String
197 STR_BCUType::decode ()
199 char buf[200];
200 sprintf (buf, "Maskversion: %04x\n", bcutype);
201 return buf;
204 STR_Code::STR_Code ()
208 bool
209 STR_Code::init (const CArray & c)
211 code.set (c.array () + 4, c () - 4);
212 return true;
215 CArray
216 STR_Code::toArray ()
218 CArray d;
219 uint16_t len = 2 + code ();
220 d.resize (2 + len);
221 d[0] = (len >> 8) & 0xff;
222 d[1] = (len) & 0xff;
223 d[2] = (L_CODE >> 8) & 0xff;
224 d[3] = (L_CODE) & 0xff;
225 d.setpart (code, 4);
226 return d;
229 String
230 STR_Code::decode ()
232 char buf[200];
233 String s;
234 int i;
235 sprintf (buf, "Code:\n");
236 s = buf;
237 return s + HexDump (code);
240 STR_StringParameter::STR_StringParameter ()
242 addr = 0;
243 length = 0;
246 bool
247 STR_StringParameter::init (const CArray & c)
249 const uchar *d;
250 if (c () < 9)
251 return false;
252 addr = c[4] << 8 | c[5];
253 length = c[6] << 8 | c[7];
254 if (c[c () - 1])
255 return false;
256 d = &c[8];
257 while (*d)
258 d++;
259 if (d != &c[c () - 1])
260 return false;
261 name = (const char *) c.array () + 8;
262 return true;
265 CArray
266 STR_StringParameter::toArray ()
268 CArray d;
269 uint16_t len = 7 + strlen (name ());
270 d.resize (2 + len);
271 d[0] = (len >> 8) & 0xff;
272 d[1] = (len) & 0xff;
273 d[2] = (L_STRING_PAR >> 8) & 0xff;
274 d[3] = (L_STRING_PAR) & 0xff;
275 d[4] = (addr >> 8) & 0xff;
276 d[5] = (addr) & 0xff;
277 d[6] = (length >> 8) & 0xff;
278 d[7] = (length) & 0xff;
279 d.setpart ((const uchar *) name (), 8, strlen (name ()) + 1);
280 return d;
283 String
284 STR_StringParameter::decode ()
286 char buf[200];
287 sprintf (buf, "StringParameter: addr=%04x id=%s length=%d\n", addr, name (),
288 length);
289 return buf;
292 STR_IntParameter::STR_IntParameter ()
294 name = 0;
295 type = 0;
298 bool
299 STR_IntParameter::init (const CArray & c)
301 const uchar *d;
302 if (c () < 8)
303 return false;
304 addr = c[4] << 8 | c[5];
305 type = (int8_t) c[6];
306 if (c[c () - 1])
307 return false;
308 d = &c[7];
309 while (*d)
310 d++;
311 if (d != &c[c () - 1])
312 return false;
313 name = (const char *) c.array () + 7;
314 return true;
317 CArray
318 STR_IntParameter::toArray ()
320 CArray d;
321 uint16_t len = 6 + strlen (name ());
322 d.resize (2 + len);
323 d[0] = (len >> 8) & 0xff;
324 d[1] = (len) & 0xff;
325 d[2] = (L_INT_PAR >> 8) & 0xff;
326 d[3] = (L_INT_PAR) & 0xff;
327 d[4] = (addr >> 8) & 0xff;
328 d[5] = (addr) & 0xff;
329 d[6] = (type) & 0xff;
330 d.setpart ((const uchar *) name (), 7, strlen (name ()) + 1);
331 return d;
334 String
335 STR_IntParameter::decode ()
337 char buf[200];
338 sprintf (buf, "IntParameter: addr=%04x id=%s type=%s %d bytes\n", addr,
339 name (), type < 0 ? "signed" : "unsigned", 1 << (abs (type) - 1));
340 return buf;
343 STR_FloatParameter::STR_FloatParameter ()
345 addr = 0;
348 bool
349 STR_FloatParameter::init (const CArray & c)
351 const uchar *d;
352 if (c () < 7)
353 return false;
354 addr = c[4] << 8 | c[5];
355 if (c[c () - 1])
356 return false;
357 d = &c[6];
358 while (*d)
359 d++;
360 if (d != &c[c () - 1])
361 return false;
362 name = (const char *) c.array () + 6;
363 return true;
366 CArray
367 STR_FloatParameter::toArray ()
369 CArray d;
370 uint16_t len = 5 + strlen (name ());
371 d.resize (2 + len);
372 d[0] = (len >> 8) & 0xff;
373 d[1] = (len) & 0xff;
374 d[2] = (L_FLOAT_PAR >> 8) & 0xff;
375 d[3] = (L_FLOAT_PAR) & 0xff;
376 d[4] = (addr >> 8) & 0xff;
377 d[5] = (addr) & 0xff;
378 d.setpart ((const uchar *) name (), 6, strlen (name ()) + 1);
379 return d;
382 String
383 STR_FloatParameter::decode ()
385 char buf[200];
386 sprintf (buf, "FloatParameter: addr=%04x id=%s\n", addr, name ());
387 return buf;
390 STR_ListParameter::STR_ListParameter ()
392 addr = 0;
395 bool
396 STR_ListParameter::init (const CArray & c)
398 uint16_t el, i;
399 const uchar *d, *d1;
400 if (c () < 9)
401 return false;
402 addr = c[4] << 8 | c[5];
403 el = c[6] << 8 | c[7];
404 if (c[c () - 1])
405 return false;
406 d = &c[8];
407 d1 = d;
408 while (*d)
409 d++;
410 if (d > &c[c () - 1])
411 return false;
412 name = (const char *) d1;
413 d1 = ++d;
414 if (d > &c[c () - 1])
415 return false;
416 elements.resize (el);
417 for (i = 0; i < el; i++)
419 while (*d)
420 d++;
421 if (d > &c[c () - 1])
422 return false;
423 elements[i] = (const char *) d1;
424 d1 = ++d;
425 if (d > &c[c ()])
426 return false;
428 if (d != &c[c ()])
429 return false;
430 return true;
433 CArray
434 STR_ListParameter::toArray ()
436 CArray d;
437 uint16_t i, p;
438 uint16_t len = 7 + strlen (name ());
439 for (i = 0; i < elements (); i++)
440 len += strlen (elements[i] ()) + 1;
441 d.resize (2 + len);
442 d[0] = (len >> 8) & 0xff;
443 d[1] = (len) & 0xff;
444 d[2] = (L_LIST_PAR >> 8) & 0xff;
445 d[3] = (L_LIST_PAR) & 0xff;
446 d[4] = (addr >> 8) & 0xff;
447 d[5] = (addr) & 0xff;
448 d[6] = (elements () >> 8) & 0xff;
449 d[7] = (elements ()) & 0xff;
450 d.setpart ((const uchar *) name (), 8, strlen (name ()) + 1);
451 p = 8 + strlen (name ()) + 1;
452 for (i = 0; i < elements (); p += strlen (elements[i] ()) + 1, i++)
453 d.setpart ((const uchar *) elements[i] (), p,
454 strlen (elements[i] ()) + 1);
455 return d;
458 String
459 STR_ListParameter::decode ()
461 char buf[200];
462 String s;
463 sprintf (buf, "ListParameter: addr=%04x id=%s elements=", addr, name ());
464 s = buf;
465 for (int i = 0; i < elements (); i++)
467 sprintf (buf, "%s,", elements[i] ());
468 s += buf;
470 s += "\n";
471 return s;
474 STR_GroupObject::STR_GroupObject ()
476 no = 0;
479 bool
480 STR_GroupObject::init (const CArray & c)
482 const uchar *d;
483 if (c () < 6)
484 return false;
485 no = c[4];
486 if (c[c () - 1])
487 return false;
488 d = &c[5];
489 while (*d)
490 d++;
491 if (d != &c[c () - 1])
492 return false;
493 name = (const char *) c.array () + 5;
494 return true;
497 String
498 STR_GroupObject::decode ()
500 char buf[200];
501 sprintf (buf, "GROUP_OBJECT %d: id=%s\n", no, name ());
502 return buf;
505 CArray
506 STR_GroupObject::toArray ()
508 CArray d;
509 uint16_t len = 4 + strlen (name ());
510 d.resize (2 + len);
511 d[0] = (len >> 8) & 0xff;
512 d[1] = (len) & 0xff;
513 d[2] = (L_GROUP_OBJECT >> 8) & 0xff;
514 d[3] = (L_GROUP_OBJECT) & 0xff;
515 d[4] = (no) & 0xff;
516 d.setpart ((const uchar *) name (), 5, strlen (name ()) + 1);
517 return d;
520 STR_BCU1Size::STR_BCU1Size ()
522 textsize = 0;
523 stacksize = 0;
524 datasize = 0;
525 bsssize = 0;
528 bool
529 STR_BCU1Size::init (const CArray & c)
531 if (c () != 12)
532 return false;
533 textsize = c[4] << 8 | c[5];
534 stacksize = c[6] << 8 | c[7];
535 datasize = c[8] << 8 | c[9];
536 bsssize = c[10] << 8 | c[11];
537 return true;
540 CArray
541 STR_BCU1Size::toArray ()
543 CArray d;
544 uint16_t len = 10;
545 d.resize (2 + len);
546 d[0] = (len >> 8) & 0xff;
547 d[1] = (len) & 0xff;
548 d[2] = (L_BCU1_SIZE >> 8) & 0xff;
549 d[3] = (L_BCU1_SIZE) & 0xff;
550 d[4] = (textsize >> 8) & 0xff;
551 d[5] = (textsize) & 0xff;
552 d[6] = (stacksize >> 8) & 0xff;
553 d[7] = (stacksize) & 0xff;
554 d[8] = (datasize >> 8) & 0xff;
555 d[9] = (datasize) & 0xff;
556 d[10] = (bsssize >> 8) & 0xff;
557 d[11] = (bsssize) & 0xff;
558 return d;
561 String
562 STR_BCU1Size::decode ()
564 char buf[200];
565 sprintf (buf, "BCU1_SIZE: text:%d stack:%d data:%d bss:%d\n", textsize,
566 stacksize, datasize, bsssize);
567 return buf;
570 STR_BCU2Size::STR_BCU2Size ()
572 textsize = 0;
573 stacksize = 0;
574 lo_datasize = 0;
575 lo_bsssize = 0;
576 hi_datasize = 0;
577 hi_bsssize = 0;
580 bool
581 STR_BCU2Size::init (const CArray & c)
583 if (c () != 16)
584 return false;
585 textsize = c[4] << 8 | c[5];
586 stacksize = c[6] << 8 | c[7];
587 lo_datasize = c[8] << 8 | c[9];
588 lo_bsssize = c[10] << 8 | c[11];
589 hi_datasize = c[12] << 8 | c[13];
590 hi_bsssize = c[14] << 8 | c[15];
591 return true;
594 CArray
595 STR_BCU2Size::toArray ()
597 CArray d;
598 uint16_t len = 14;
599 d.resize (2 + len);
600 d[0] = (len >> 8) & 0xff;
601 d[1] = (len) & 0xff;
602 d[2] = (L_BCU2_SIZE >> 8) & 0xff;
603 d[3] = (L_BCU2_SIZE) & 0xff;
604 d[4] = (textsize >> 8) & 0xff;
605 d[5] = (textsize) & 0xff;
606 d[6] = (stacksize >> 8) & 0xff;
607 d[7] = (stacksize) & 0xff;
608 d[8] = (lo_datasize >> 8) & 0xff;
609 d[9] = (lo_datasize) & 0xff;
610 d[10] = (lo_bsssize >> 8) & 0xff;
611 d[11] = (lo_bsssize) & 0xff;
612 d[12] = (hi_datasize >> 8) & 0xff;
613 d[13] = (hi_datasize) & 0xff;
614 d[14] = (hi_bsssize >> 8) & 0xff;
615 d[15] = (hi_bsssize) & 0xff;
616 return d;
619 String
620 STR_BCU2Size::decode ()
622 char buf[200];
623 sprintf (buf,
624 "BCU2_SIZE: text:%d stack:%d lo_data:%d lo_bss:%d hi_data:%d hi_bss:%d\n",
625 textsize, stacksize, lo_datasize, lo_bsssize, hi_datasize,
626 hi_bsssize);
627 return buf;
630 STR_BCU2Start::STR_BCU2Start ()
632 addrtab_start = 0;
633 addrtab_size = 0;
634 assoctab_start = 0;
635 assoctab_size = 0;
636 readonly_start = 0;
637 readonly_end = 0;
638 param_start = 0;
639 param_end = 0;
641 obj_ptr = 0;
642 obj_count = 0;
643 appcallback = 0;
644 groupobj_ptr = 0;
645 seg0 = 0;
646 seg1 = 0;
647 sphandler = 0;
648 initaddr = 0;
649 runaddr = 0;
650 saveaddr = 0;
651 eeprom_start = 0;
652 eeprom_end = 0;
653 poll_addr = 0;
654 poll_slot = 0;
657 bool
658 STR_BCU2Start::init (const CArray & c)
660 if (c () != 47)
661 return false;
662 addrtab_start = c[4] << 8 | c[5];
663 addrtab_size = c[6] << 8 | c[7];
664 assoctab_start = c[8] << 8 | c[9];
665 assoctab_size = c[10] << 8 | c[11];
666 readonly_start = c[12] << 8 | c[13];
667 readonly_end = c[14] << 8 | c[15];
668 param_start = c[16] << 8 | c[17];
669 param_end = c[18] << 8 | c[19];
670 obj_ptr = c[20] << 8 | c[21];
671 obj_count = c[22] << 8 | c[23];
672 appcallback = c[24] << 8 | c[25];
673 groupobj_ptr = c[26] << 8 | c[27];
674 seg0 = c[28] << 8 | c[29];
675 seg1 = c[30] << 8 | c[31];
676 sphandler = c[32] << 8 | c[33];
677 initaddr = c[34] << 8 | c[35];
678 runaddr = c[36] << 8 | c[37];
679 saveaddr = c[38] << 8 | c[39];
680 eeprom_start = c[40] << 8 | c[41];
681 eeprom_end = c[42] << 8 | c[43];
682 poll_addr = c[44] << 8 | c[45];
683 poll_slot = c[46];
684 return true;
687 CArray
688 STR_BCU2Start::toArray ()
690 CArray d;
691 uint16_t len = 45;
692 d.resize (2 + len);
693 d[0] = (len >> 8) & 0xff;
694 d[1] = (len) & 0xff;
695 d[2] = (L_BCU2_INIT >> 8) & 0xff;
696 d[3] = (L_BCU2_INIT) & 0xff;
697 d[4] = (addrtab_start >> 8) & 0xff;
698 d[5] = (addrtab_start) & 0xff;
699 d[6] = (addrtab_size >> 8) & 0xff;
700 d[7] = (addrtab_size) & 0xff;
701 d[8] = (assoctab_start >> 8) & 0xff;
702 d[9] = (assoctab_start) & 0xff;
703 d[10] = (assoctab_size >> 8) & 0xff;
704 d[11] = (assoctab_size) & 0xff;
705 d[12] = (readonly_start >> 8) & 0xff;
706 d[13] = (readonly_start) & 0xff;
707 d[14] = (readonly_end >> 8) & 0xff;
708 d[15] = (readonly_end) & 0xff;
709 d[16] = (param_start >> 8) & 0xff;
710 d[17] = (param_start) & 0xff;
711 d[18] = (param_end >> 8) & 0xff;
712 d[19] = (param_end) & 0xff;
713 d[20] = (obj_ptr >> 8) & 0xff;
714 d[21] = (obj_ptr) & 0xff;
715 d[22] = (obj_count >> 8) & 0xff;
716 d[23] = (obj_count) & 0xff;
717 d[24] = (appcallback >> 8) & 0xff;
718 d[25] = (appcallback) & 0xff;
719 d[26] = (groupobj_ptr >> 8) & 0xff;
720 d[27] = (groupobj_ptr) & 0xff;
721 d[28] = (seg0 >> 8) & 0xff;
722 d[29] = (seg0) & 0xff;
723 d[30] = (seg1 >> 8) & 0xff;
724 d[31] = (seg1) & 0xff;
725 d[32] = (sphandler >> 8) & 0xff;
726 d[33] = (sphandler) & 0xff;
727 d[34] = (initaddr >> 8) & 0xff;
728 d[35] = (initaddr) & 0xff;
729 d[36] = (runaddr >> 8) & 0xff;
730 d[37] = (runaddr) & 0xff;
731 d[38] = (saveaddr >> 8) & 0xff;
732 d[39] = (saveaddr) & 0xff;
733 d[40] = (eeprom_start >> 8) & 0xff;
734 d[41] = (eeprom_start) & 0xff;
735 d[42] = (eeprom_end >> 8) & 0xff;
736 d[43] = (eeprom_end) & 0xff;
737 d[44] = (poll_addr >> 8) & 0xff;
738 d[45] = (poll_addr) & 0xff;
739 d[46] = (poll_slot) & 0xff;
740 return d;
743 String
744 STR_BCU2Start::decode ()
746 char buf[600];
747 sprintf (buf,
748 "BCU2_INIT: init:%04X run:%04X save:%04X addr_tab:%04X(%d) assoc_tab:%04X(%d) text:%04X-%04X\n"
749 " param:%04X-%04X obj:%04X(%d) appcallback:%04X\n"
750 " groupobj:%04X seg0:%04X seg1:%04X sphandler:%04X eeprom:%04X-%04X poll_addr:%04X poll_slot:%d\n",
751 initaddr, runaddr, saveaddr, addrtab_start, addrtab_size,
752 assoctab_start, assoctab_size, readonly_start, readonly_end,
753 param_start, param_end, obj_ptr, obj_count, appcallback,
754 groupobj_ptr, seg0, seg1, sphandler, eeprom_start, eeprom_end,
755 poll_addr, poll_slot);
756 return buf;
759 STR_BCU2Key::STR_BCU2Key ()
761 installkey = 0xFFFFFFFF;
764 bool
765 STR_BCU2Key::init (const CArray & c)
767 unsigned i;
768 if (c () % 4)
769 return false;
770 if (c () < 8)
771 return false;
772 installkey = (c[4] << 24) | (c[5] << 16) | (c[6] << 8) | (c[7]);
773 for (i = 8; i < c (); i += 4)
774 keys.add ((c[i] << 24) | (c[i + 1] << 16) | (c[i + 2] << 8) | (c[i + 3]));
775 return true;
778 CArray
779 STR_BCU2Key::toArray ()
781 CArray d;
782 int i;
783 uint16_t len = keys () * 4 + 4 + 2;
784 d.resize (2 + len);
785 d[0] = (len >> 8) & 0xff;
786 d[1] = (len) & 0xff;
787 d[2] = (L_BCU2_KEY >> 8) & 0xff;
788 d[3] = (L_BCU2_KEY) & 0xff;
789 d[4] = (installkey >> 24) & 0xff;
790 d[5] = (installkey >> 16) & 0xff;
791 d[6] = (installkey >> 8) & 0xff;
792 d[7] = (installkey >> 0) & 0xff;
793 for (i = 0; i < keys (); i++)
795 d[8 + 4 * i] = (keys[i] >> 24) & 0xff;
796 d[9 + 4 * i] = (keys[i] >> 16) & 0xff;
797 d[10 + 4 * i] = (keys[i] >> 8) & 0xff;
798 d[11 + 4 * i] = (keys[i] >> 0) & 0xff;
800 return d;
804 String
805 STR_BCU2Key::decode ()
807 char buf[200];
808 String s;
809 int i;
810 sprintf (buf, "BCU2_KEY: install:%08X ", installkey);
811 s = buf;
812 for (i = 0; i < keys (); i++)
814 sprintf (buf, "level%d: %08X ", i, keys[i]);
815 s += buf;
817 return s;
820 Image::Image ()
824 Image::~Image ()
826 for (int i = 0; i < str (); i++)
827 if (str[i])
828 delete str[i];
831 String
832 Image::decode ()
834 String s = "BCU Memory Image\n";
835 for (int i = 0; i < str (); i++)
836 s += str[i]->decode ();
837 return s;
840 CArray
841 Image::toArray ()
843 CArray data;
844 data.resize (10);
845 data[0] = 0xbc;
846 data[1] = 0x68;
847 data[2] = 0x0c;
848 data[3] = 0x05;
849 data[4] = 0xbc;
850 data[5] = 0x68;
851 data[6] = 0x0c;
852 data[7] = 0x05;
853 for (int i = 0; i < str (); i++)
854 data.setpart (str[i]->toArray (), data ());
855 data[8] = (data () >> 8) & 0xff;
856 data[9] = (data ()) & 0xff;
857 return data;
861 Image::findStreamNumber (STR_Type t)
863 for (int i = 0; i < str (); i++)
864 if (str[i]->getType () == t)
865 return i;
866 return -1;
869 STR_Stream *
870 Image::findStream (STR_Type t)
872 int i = findStreamNumber (t);
873 if (i == -1)
874 return 0;
875 else
876 return str[i];
879 Image *
880 Image::fromArray (CArray c)
882 uint16_t pos = 10;
883 uint16_t len;
884 if (c () < 10)
885 return 0;
886 if (c[0] != 0xbc)
887 return 0;
888 if (c[1] != 0x68)
889 return 0;
890 if (c[2] != 0x0c)
891 return 0;
892 if (c[3] != 0x05)
893 return 0;
894 if (c[4] != 0xbc)
895 return 0;
896 if (c[5] != 0x68)
897 return 0;
898 if (c[6] != 0x0c)
899 return 0;
900 if (c[7] != 0x05)
901 return 0;
902 if (c[8] != ((c () >> 8) & 0xff))
903 return 0;
904 if (c[9] != ((c ()) & 0xff))
905 return 0;
906 Image *i = new Image;
907 while (pos < c ())
909 if (pos + 4 >= c ())
911 delete i;
912 return 0;
914 len = c[pos] << 8 | c[pos + 1];
915 if (pos + 2 + len > c () || len < 2)
917 delete i;
918 return 0;
920 i->str.add (STR_Stream::fromArray (CArray (&c[pos], len + 2)));
921 pos += 2 + len;
923 return i;
926 bool
927 Image::isValid ()
929 return findStreamNumber (S_Invalid) == -1;