2 #include <stdlib.h> //exit, malloc
3 #include <stdio.h> //print
4 #include <stdarg.h> //va_args
5 #include <string.h> //memset, str*
8 #include <unistd.h> //u8_* functions
9 #include <unitypes.h> //uint8_t as a char
10 #include <unistr.h> //u32_cpy
11 #include <unistdio.h> //ulc_fprintf
18 #define do_error(...) exit(-1)
19 #define XXH_PRIVATE_API
20 #include "../xxHash/xxhash.h"
21 #define STB_IMAGE_IMPLEMENTATION
22 #include "../stb/stb_image.h"
23 #define STB_IMAGE_WRITE_IMPLEMENTATION
24 #include "../stb/stb_image_write.h"
27 void ir_binout_init(struct ir_class_t
*);
29 /* Memory Allocation */
30 #define struct_alloc(_T) ((struct _T*) stack_alloc(&datapages, sizeof(struct _T)))
32 struct pagelist_t linkpages
, datapages
;
34 enum model_type
{ SS
};
35 /* Binaryout out structure definitions */
36 struct bin_img_info_t
{
39 int fwidth
; //map and frame width
40 int fheight
; //map and frame height
44 struct bin_ht_header_t
{
48 struct bin_ht_entry_t
{
52 struct bin_class_header_t
{
53 struct bin_ht_header_t child_ht
;
54 struct bin_ht_header_t rootset_ht
;
57 struct bin_set_header_t
{
58 struct bin_ht_header_t child_ht
;
59 long sdat_start
; //points to setdata_header
62 struct bin_setdata_header_t
{
63 struct bin_ht_header_t variant_ht
;
66 struct bin_model_header_t
{ //one for each framebox, currently
67 long facing_array_start
;
70 struct bin_frame_header_t
{
87 struct bin_pixel_node_t
{
88 struct bin_pixel_node_t
* next
;
89 struct bin_pixel_t data
;
91 struct bin_attachment_header_t
{
92 int num_attachment_lists
;
95 struct bin_attachment_t
{
99 /* Read out of the als, after first ir pass, resolves the
100 attach_pos of the src-set that created the attachment_list
101 to the header that describes the attachment_list */
102 struct bin_attachment_list_t
{
104 struct bin_attachment_t
** attachments
;
108 struct bin_attachment_list_t
**attachment_stack
, **asp
; //attachment_stack, attachment_stack_pointer
113 #define NAMEHASH(name, domain) (XXH32(name, u8_strlen(name), 0XCEED ) & domain)
121 set_fb
= ir_set_framebox(set
);
123 for (iter
= set_fb
; iter
!= NULL
; iter
= ir_setdata_nextsib(iter
))
129 int bin_class_sibcount
134 for (iter
= class; iter
!= NULL
; iter
= ir_class_nextsib(iter
))
145 for (iter
= set
; iter
!= NULL
; iter
= ir_set_nextsib(iter
))
150 /* Given a position and a size, checks if the bytes are null and returns
151 the file position to where it started. 1 if not null, 0 if null*/
152 /* TODO: Determine why fseeking file past end sets bytes to -1, and not 0 */
154 int bytes_null( int len
, int pos
)
156 { if(fgetc(binaryout
) > 0)
157 { fseek(binaryout
, pos
, SEEK_SET
);
161 fseek(binaryout
, pos
, SEEK_SET
);
164 /* Checks if the key at entrypos is the same as the parameter key. Returns
165 1 if so, 0 if not. */
167 int bin_keys_identical
172 fseek(binaryout
, entry_pos
, SEEK_SET
);
173 fscanf(binaryout
, "%u", &curr_key
);
179 long bin_traverse_class(ir_class
);
180 /* Takes root class and begins processing */
182 ir_binout_init(ir_class root_class
)
183 { binaryout
= fopen("binaryout", "w+");
184 asp
= attachment_stack
;
185 pagelist_init(datapages
, (size_t) SYS_PAGESIZE
);
186 pagelist_init(linkpages
, (size_t) SYS_PAGESIZE
);
187 bin_traverse_class(root_class
);
190 #define ENTRY_OCCUPIED() (bytes_null(sizeof(ht_entry->key), entry_pos))
191 #define WRITE_ENTRY() do { \
192 if(fseek(binaryout, entry_pos, SEEK_SET) == -1) wprintf("fseek failed with %s", strerror(errno)); \
193 fwrite(&ht_entry, sizeof ht_entry, 1, binaryout); \
195 #define LOOP_ENTRY(_HTSTART) (entry_pos = _HTSTART)
196 #define INC_ENTRY() do { \
197 entry_pos += sizeof(ht_entry); \
198 if(fseek(binaryout, entry_pos, SEEK_SET) == -1) eprintf("fseek failed with %s", strerror(errno)); \
200 #define HT_END(_HTEND) (entry_pos >= _HTEND) //just in case at last entry
202 /* TODO: Should overwrite be a default? */
206 struct bin_ht_entry_t
* ht_entry
,
209 { long entry_pos
, ht_end
;
211 ht_end
= ht_start
+ ht_size
;
212 entry_pos
= ht_start
+ sizeof(ht_entry
) * ht_entry
->key
;
213 fseek(binaryout
, entry_pos
, SEEK_SET
);
215 if (!ENTRY_OCCUPIED())
216 { uprintf("key not occupied\n");
219 while( ENTRY_OCCUPIED() )
221 { if(bin_keys_identical(entry_pos
, ht_entry
->key
))
224 { eprintf("error in hashtable insertion, keys are identical");
228 LOOP_ENTRY(ht_start
);
237 |--------------------|
239 |--------------------|
241 |--------------------|
243 |--------------------|
244 | classchild header |
248 long bin_traverse_set(ir_set
);
250 #define HT_INIT(_START, _SIZE, _INIT_ENTRIES) do { \
251 _SIZE = _INIT_ENTRIES ? (_INIT_ENTRIES * (sizeof(struct bin_ht_entry_t) << 1)): 0; \
252 _START = ftell(binaryout); \
253 fseek(binaryout, _SIZE, SEEK_CUR); \
259 struct bin_class_header_t class_header
;
260 struct bin_ht_entry_t ht_entry
;
261 long class_start
, classht_start
, classht_size
, rootsetht_start
, rootsetht_size
;
262 int num_csibs
, num_ssibs
;
265 class_start
= ftell(binaryout
);
266 class_name
= ir_class_name(class);
268 num_csibs
= bin_class_sibcount(class);
269 num_ssibs
= bin_set_sibcount(ir_class_rootset(class));
271 /* alloc space (before hash tables) for class header */
272 class_header
.namelen
= u8_strlen(class_name
);
273 fseek(binaryout
, class_start
+ sizeof(class_header
) + class_header
.namelen
,SEEK_SET
);
275 HT_INIT(classht_start
, classht_size
, num_csibs
);
276 HT_INIT(rootsetht_start
, rootsetht_size
, num_ssibs
);
278 /* TODO: Figure out generic way to output headers */
279 /* populate class header */
280 class_header
.child_ht
.entries
= num_csibs
;
281 class_header
.child_ht
.start
= classht_start
;
282 class_header
.rootset_ht
.entries
= num_ssibs
;
283 class_header
.rootset_ht
.start
= rootsetht_start
;
284 fseek(binaryout
, class_start
, SEEK_SET
); //seek back to where we allocated header
285 fwrite(&class_header
, sizeof(class_header
), 1, binaryout
);
286 fwrite(class_name
, class_header
.namelen
, 1, binaryout
);
288 /* Start populating root_set hash table */
289 for ( siter
= ir_class_rootset(class); siter
!= NULL
; siter
= ir_set_nextsib(siter
))
290 { fseek(binaryout
, 0, SEEK_END
);
291 ht_entry
.key
= NAMEHASH(ir_set_name(siter
), num_ssibs
<< 1);
292 ht_entry
.value
= bin_traverse_set(siter
);
293 bin_insert_ht_entry(rootsetht_start
, rootsetht_size
, &ht_entry
, 0);
296 /* Start populating class child hash table */
297 for ( citer
= ir_class_nextchild(class); citer
!= NULL
; citer
= ir_class_nextsib(citer
))
298 { if(chdir((char*) class_name
))
299 eprintf("CHDIR %U from %s\n",(char*) class_name
,getcwd(NULL
,255));
300 fseek(binaryout
, 0, SEEK_END
);
301 ht_entry
.key
= NAMEHASH(ir_class_name(citer
), num_csibs
<< 1);
302 ht_entry
.value
= bin_traverse_class(citer
);
303 bin_insert_ht_entry(classht_start
, classht_size
, &ht_entry
, 0);
305 eprintf("CHDIR ..\n");
311 long bin_process_sdat( ir_set
);
314 |-----------------| |
316 |-----------------| |
317 ---| setchild ht |<--
318 | |-----------------|
319 |->| setchild header |
327 struct bin_set_header_t header
;
328 struct bin_ht_entry_t ht_entry
;
329 int num_child
, setname_len
;
330 long childht_start
, childht_size
, set_start
;
333 set_start
= ftell(binaryout
);
334 set_name
= ir_set_name(set
);
336 /* alloc space for set header */
337 setname_len
= u8_strlen(set_name
);
338 fseek(binaryout
, sizeof(struct bin_set_header_t
) + setname_len
, SEEK_CUR
);
340 /* process the set data */
341 header
.sdat_start
= bin_process_sdat(set
);
343 /* Setup child hash table for current sets children */
344 num_child
= bin_set_sibcount(ir_set_nextchild(set
));
345 HT_INIT(childht_start
, childht_size
, num_child
);
347 /* populate header, write to file */
348 header
.child_ht
.entries
= num_child
;
349 header
.child_ht
.start
= childht_start
;
350 fseek(binaryout
, set_start
, SEEK_SET
);
351 fwrite(&header
, sizeof(struct bin_set_header_t
), 1, binaryout
);
352 fwrite(set_name
, setname_len
, 1, binaryout
);
354 for(iter
= ir_set_nextchild(set
); iter
!= NULL
; iter
= ir_set_nextsib(iter
))
355 { fseek(binaryout
, 0, SEEK_END
);
356 ht_entry
.key
= NAMEHASH(ir_set_name(iter
), num_child
<< 1);
357 ht_entry
.value
= bin_traverse_set(iter
);
358 bin_insert_ht_entry(childht_start
, childht_size
, &ht_entry
, 0);
362 ir_set_assign_fpos(set
, set_start
);
370 | 1st variant data | -- variant == framebox
378 void bin_insert_links(int, struct bin_ht_header_t
*, long);
379 struct bin_pixel_node_t
* bin_find_default_pixel_list(ir_set
);
380 void bin_process_frameboxes(ir_set
, struct bin_ht_header_t
*, struct bin_pixel_node_t
*);
381 int bin_process_links(ir_set
, ir_setdata
);
383 /* Init the variant hash table for the set, process the sets links and add them to link_stack
384 and variant hash table, and then output the actual framedata */
388 { struct bin_setdata_header_t header
;
389 struct bin_attachment_list_t attachment_list
;
390 struct bin_pixel_node_t
*default_pixel_list
;
391 struct bin_ht_header_t ht_header
;
392 long varht_start
, varht_size
, sdat_start
;
393 int num_entries
, num_links
;
394 ir_setdata olink_head
;
396 sdat_start
= ftell(binaryout
);
398 /* Alloc position for sdat_header */
399 fseek(binaryout
, sizeof(struct bin_setdata_header_t
), SEEK_CUR
);
401 num_links
= bin_process_links(set
, olink_head
);
402 num_entries
= bin_set_varcount(set
) + num_links
;
404 HT_INIT(varht_start
, varht_size
, num_entries
);
406 /* Populate the sdat_header */
407 fseek(binaryout
, 0, sdat_start
);
408 header
.variant_ht
.start
= ht_header
.start
= varht_start
;
409 header
.variant_ht
.entries
= ht_header
.entries
= num_entries
;
410 attachment_list
.filepos
= header
.attach_pos
= ftell(binaryout
) + sizeof(varht_start
) + sizeof(num_entries
);
411 fwrite(&header
, sizeof(header
), 1, binaryout
);
412 fseek(binaryout
, 0, SEEK_END
);
414 /* insert the links that were processed into the variant hash table */
415 bin_insert_links(num_links
, &ht_header
, attachment_list
.filepos
);
416 /* Determine the default pixel list for all of the frameboxes */
417 default_pixel_list
= bin_find_default_pixel_list(set
);
418 /* Output each framebox, and insert it into the variant hash table */
419 bin_process_frameboxes(set
, &ht_header
, default_pixel_list
);
421 /* TODO: Convert the default pixel list to an attachment_list and then push the */
422 /* sdats attachment_list onto the attachment_stack so it can be procesed */
429 /* Adds a vlink onto the stack_alloc to be popped during the processing of the
430 sets variant hash table. If the vlink has a name, its a vlink to a single
431 variant. if the vlink doesnt have a name, its the vlink to an entire variant
432 hash table, and each variant (framebox) needs to be added */
438 { struct bin_plink_t
* plp
;
445 /* TODO: Macroize? or not worth? */
446 link_name
= ir_setdata_name(vlink
);
449 { plp
= struct_alloc(bin_plink_t
);
450 plp
->src_pos
= 0; // TBD @ process_setdata
451 plp
->name
= link_name
;
452 plp
->trg_set
= trg_set
;
456 else // linking a variant hash table
457 for (fiter
= ir_set_framebox(trg_set
); fiter
!= NULL
; fiter
= ir_setdata_nextsib(fiter
))
458 { plp
= struct_alloc(bin_plink_t
);
459 plp
->src_pos
= 0; // TBD @ process_setdata
460 plp
->name
= ir_setdata_name(fiter
);
461 plp
->trg_set
= trg_set
;
470 /* Adds an mlink to the stack_alloc, to be processed later */
476 { struct bin_plink_t
* plp
;
478 mlink_name
= ir_setdata_name(mlink
);
479 plp
= struct_alloc(bin_plink_t
);
480 plp
->src_pos
= 0; //TBD after resolving the childlist | TODO: attach_pos?
481 if(mlink_name
) plp
->name
= mlink_name
;
482 plp
->trg_set
= trg_set
;
488 /* TODO: implement this */
489 /* Determine if olink is already part of the olink_list.
490 if it is, theres a cycle, return 1. Else return 0. */
494 ir_setdata olink_head
)
504 /* Given a set, determine the number of links it has and process each link and
505 then add them to stack_alloc, where they will be popped off and further processed. */
509 ir_setdata olink_head
512 linkdata liter
; //link iter
517 for(liter
= ir_set_link(src_set
); liter
!= NULL
; liter
= ir_setdata_nextsib((ir_setdata
) liter
))
518 { trg_set
= ir_set_from_ref(ir_linkdata_ref(liter
));
519 switch (ir_linkdata_type(liter
)) {
521 if (olink_cycle(liter
, olink_head
)) //TODO: stack of olinks to iterate and check for cycles?
523 num_links
+= bin_process_vlink(liter
, trg_set
);
524 num_links
+= bin_process_mlink(liter
, trg_set
);
525 num_links
+= bin_process_links(trg_set
, liter
);
528 num_links
+= bin_process_vlink(liter
, trg_set
);
531 num_links
+= bin_process_mlink(liter
, trg_set
);
533 case ALINK
: //TODO: ?
540 /* Insert both mlinks and vlinks into the link stack, after determining their src_pos. Vlinks
541 have an additional requirement of being added into the variant hash table */
542 #define pop_linkp() (*(struct bin_plink_t**) pagelist_pop(&datapages, sizeof(struct bin_plink_t*)))
543 #define PUSH_PLINK(_LINK) (*(struct bin_plink_t**) stack_alloc(&linkpages, sizeof (_LINK)) = _LINK )
547 struct bin_ht_header_t
* ht
,
550 { struct bin_plink_t
* plp
;
551 struct bin_ht_entry_t ht_entry
;
554 /* Insert vlinks into hash table, put v/mlinks on link stack to be processed later */
555 for ( i
= 0; i
< num_links
; i
++)
559 plp
->trg_set
= plp
->trg_set
;
560 plp
->src_pos
= attach_pos
;
564 ht_entry
.key
= NAMEHASH(plp
->name
, ht
->entries
<< 1);
566 bin_insert_ht_entry(ht
->start
, ht
->entries
* sizeof(ht_entry
), &ht_entry
, 0);
567 plp
->src_pos
= ht_entry
.key
+ sizeof(ht_entry
.key
);
580 long bin_process_facing(ir_setdata
, apc_facing
, struct bin_pixel_node_t
*);
581 /* |-------------------|
583 |-------------------|
585 |-------------------|
586 | SWFACE framesheet |
587 |-------------------|
594 struct bin_pixel_node_t
* default_pixel_list
596 { struct bin_model_header_t header
;
597 long framebox_start
, index_pos
;
600 framebox_start
= ftell(binaryout
);
602 /* insert model header */
604 header
.facing_array_start
= framebox_start
+ sizeof(header
);
605 fwrite(&header
, sizeof(header
), 1, binaryout
);
607 /* Create the index array for framesheet of each direction */
608 for ( i
= SFACE
; i
< FACING_MAX
; i
++)
609 { fseek(binaryout
, 0, SEEK_END
);
610 index_pos
= bin_process_facing(framebox
, i
, default_pixel_list
); //TODO: finish process_direction
611 fseek(binaryout
, header
.facing_array_start
+ i
* sizeof(long), SEEK_SET
);
612 fwrite(&index_pos
, sizeof(long), 1, binaryout
);
615 return framebox_start
;
618 bin_process_frameboxes
620 struct bin_ht_header_t
* ht
,
621 struct bin_pixel_node_t
* default_pixel_list
623 { struct bin_ht_entry_t ht_entry
;
626 /* Insert variants into hash table to overwrite olink insertions*/
627 for ( fiter
= ir_set_framebox(set
); fiter
!= NULL
; fiter
= ir_setdata_nextsib(fiter
))
628 { fseek(binaryout
, 0, SEEK_END
);
629 ht_entry
.key
= NAMEHASH(ir_setdata_name(fiter
), ht
->entries
<< 1);
630 ht_entry
.value
= bin_process_framebox(set
, fiter
, default_pixel_list
);
631 bin_insert_ht_entry(ht
->start
, ht
->entries
* sizeof(ht_entry
), &ht_entry
, 1);
635 /* Determine clipping based on image height/width and frame height/width */
637 void bin_set_img_info
638 ( struct bin_img_info_t
* img_info
,
639 ir_setdata frame_data
641 { ir_frameinfo frameinfo
;
642 frameinfo
= ir_framedata_frameinfo(frame_data
);
643 img_info
->fwidth
= frameinfo
->w
;
644 img_info
->fheight
= frameinfo
->h
;
645 img_info
->unaligned_height
= img_info
->height
% img_info
->fheight
;
646 img_info
->unaligned_width
= img_info
->width
% img_info
->fwidth
;
649 /* |-----------------------------|
651 |-----------------------------|
652 | pixel data for frame1 - n |
653 |-----------------------------|
654 | op data for frame1 - n |
655 |-----------------------------| */
658 #define GENERATE_FILENAME(_N) ((char*) u8_strcat(_N, png_suffix))
660 ( ir_setdata framebox
,
662 struct bin_pixel_node_t
* default_pixel_list
664 { struct bin_img_info_t mapsheet_info
, framesheet_info
;
665 int num_mapchannels
, num_framechannels
, x
;
666 struct bin_frame_header_t header
;
668 unsigned char* mapdata
, * framedata
;
669 uint8_t* png_suffix
= ".png";
670 struct bin_pixel_node_t
* map_pixel_list
;
672 facing_start
= ftell(binaryout
);
675 /* Set up data pointers to mapsheet and framesheet, as well as their image infos */
676 mapdata
= stbi_load(GENERATE_FILENAME(ir_setdata_name((ir_setdata
) ir_framebox_mapsheet(framebox
,SFACE
))), &mapsheet_info
.width
, &mapsheet_info
.width
, &num_framechannels
, 0);
677 framedata
= stbi_load(GENERATE_FILENAME(ir_setdata_name((ir_setdata
) ir_framebox_framesheet(framebox
,SFACE
))), &framesheet_info
.width
, &framesheet_info
.height
, &num_mapchannels
, 0);
678 bin_set_img_info(&framesheet_info
, ir_framebox_framesheet(framebox
, SFACE
));
679 bin_set_img_info(&mapsheet_info
, ir_framebox_mapsheet(framebox
, SFACE
));
681 /* Allocate space for header */
682 fseek(binaryout
, sizeof(header
), SEEK_CUR
);
685 /* Output framesheet */
686 if(!stbi_write_png(binaryout
, framesheet_info
.width
, framesheet_info
.height
, 4, mapdata
, framesheet_info
.fwidth
))
687 eprintf("error writing out framesheet\n");
689 /* Output framesheet header */
690 header
.width
= framesheet_info
.fwidth
;
691 header
.height
= framesheet_info
.fheight
;
692 header
.frames
= framesheet_info
.width
/ framesheet_info
.fwidth
; //TODO: division is bad
693 header
.op_start
= ftell(binaryout
);
694 fseek(binaryout
, facing_start
, SEEK_SET
);
695 fwrite(&header
, sizeof(header
), 1, binaryout
);
696 fseek(binaryout
, 0, SEEK_END
);
699 /* Assuming that fheight = image height */
700 /* For each mapframe in mapsheet */
701 for ( x
= 0; x
< header
.frames
; x
++)
702 { map_pixel_list
= bin_map_to_pixel_list(mapsheet_info
, 0, x
* mapsheet_info
.fwidth
, data
);
703 if(!bin_process_map_pixel_list(default_pixel_list
, map_pixel_list
))
704 eprintf("error processing map pixel list\n");
705 bin_output_pixel_list(map_pixel_list
);
706 data
+= mapsheet_info
.fwidth
;
709 /* Determine pixel_list */
711 /* Output pixel_list */
718 /* TODO: Please rename all the functions jhc*/
720 void bin_number_pixel_list
721 ( struct bin_pixel_node_t
* pixel_list
)
723 struct bin_pixel_node_t
* iter
;
725 { iter
.data
.attach_idx
= num
++;
730 /* Assuming at this point that map_pixel_list is valid */
732 int bin_set_map_pixel_list_attach_idxs
733 ( struct bin_pixel_node_t
* default_pixel_list
,
734 struct bin_pixel_node_t
* map_pixel_list
736 { struct bin_pixel_node_t
* mapiter
, defaultiter
;
737 mapiter
= map_pixel_list
;
738 defaultiter
= default_pixel_list
;
739 while (mapiter
&& defaultiter
)
740 { /* if mapiter.data.ref == defaultiter.data.ref, assign mapiter index_idx to defaultiter */
741 if (mapiter
.data
.ref
== defauliter
.data
.ref
)
742 { defaultiter
.data
.attach_idx
= mapiter
.data
.attach_idx
;
743 mapiter
= mapiter
->next
;
744 defaultiter
= defaultiter
->next
;
747 defaultiter
= defaultiter
->next
;
751 /* map_pixel_list cannot have more pixels. for all of its pixels,
752 the refs must be represented in default pixel list. 0 if invalid, 1 if valid */
754 int bin_valid_map_pixel_list
755 ( struct bin_pixel_node_t
* default_pixel_list
,
756 struct bin_pixel_node_t
* map_pixel_list
758 { struct bin_pixel_node_t
* mapiter
, defaultiter
;
759 defaultiter
= default_pixel_list
;
760 /* check length of each to make sure default < max */
761 /* for each pixel node in default and map */
763 { for( mapiter
= map_pixel_list
; mapiter
!= NULL
; mapiter
= mapiter
->next
)
769 if(!mapiter
&& defaultiter
) //defaultiter is longer so error!
778 int bin_process_map_pixel_list
779 ( struct bin_pixel_node_t
* default_pixel_list
,
780 struct bin_pixel_node_t
* map_pixel_list
782 { /* Determine if pixel_list is valid */
784 /* Determine attach_idx of each pixel, as compared to default pixel list */
789 bin_assign_pixel_idxs
790 ( struct bin_pixel_node_t
* pixel_list
)
794 /* Insert pixel(s) into the list, z sorted */
795 /* number the pixels as you insert them */
796 struct bin_pixel_node_t
*
797 bin_insert_node_into_list
798 ( struct bin_pixel_node_t
* pixel_list_root
,
799 struct bin_pixel_node_t
* pixel_node
801 { struct bin_pixel_node_t
* head_node
, * prev_node
;
804 if(pixel_list_root
== NULL
)
805 { pixel_list_root
= pixel_node
;
808 prev_node
= head_node
= pixel_list_root
;
809 while(head_node
!= NULL
)
810 { if(pixel_node
->data
.z
> head_node
->data
.z
)
811 { if(head_node
->next
)
812 { prev_node
= head_node
;
813 head_node
= head_node
->next
;
816 { head_node
->next
= pixel_node
;
820 else if (pixel_node
->data
.z
< head_node
->data
.z
|| pixel_node
->data
.z
== head_node
->data
.z
)
821 { prev_node
->next
= pixel_node
;
822 pixel_node
->next
= head_node
;
827 return pixel_list_root
;
832 /* TODO: Finish this */
833 struct bin_pixel_node_t
*
835 ( unsigned char* data
,
841 { struct bin_pixel_node_t
* pixel_node
= NULL
;
843 { pixel_node
= struct_alloc(bin_pixel_node_t
);
844 /* get ref from 4 bytes of data */
845 pixel_node
->data
.ref
= (int) data
;
846 /* bitshift by ? to get Z */
847 pixel_node
->data
.z
= ((int) data
<< 24);
849 pixel_node
->data
.x
= x
+ init_width
;
850 pixel_node
->data
.y
= y
+ init_width
;
857 /* Returns the non null pixels of a single map */
858 /* TODO: Finish this */
859 struct bin_pixel_node_t
*
860 bin_mapframe_to_pixel_list
861 ( struct bin_img_info_t
* img_info
,
866 { int x
, y
, fheight
, fwidth
;
867 struct bin_pixel_node_t
* pixel_list
, * pixel_node
;
871 /* if frame clips, process unclippign frames */
872 if( img_info
->unaligned_width
)
873 { if(img_info
->height
< img_info
->fheight
)
874 fheight
= img_info
->height
;
876 fheight
= img_info
->fheight
;
879 fheight
= img_info
->fheight
;
880 if (img_info
->unaligned_height
)
881 { if(img_info
->width
< img_info
->fwidth
)
882 fwidth
= img_info
->width
;
884 fwidth
= img_info
->fwidth
;
887 fwidth
= img_info
->fwidth
;
891 for (y
= 0; y
< fheight
; y
++)
892 { for ( x
= 0; x
< fwidth
; x
++ )
893 { pixel_node
= bin_process_pixel(data
, x
, y
, init_height
, init_width
);
894 pixel_list
= bin_insert_node_into_list(pixel_list
, pixel_node
);
895 data
+= img_info
->width
- img_info
->fwidth
; //stride
903 int bin_pixel_list_len
904 ( struct bin_pixel_node_t
* pl
)
905 { struct bin_pixel_node_t
* plp
;
916 struct bin_pixel_node_t
*
917 bin_cmp_default_pixel_lists
918 ( struct bin_pixel_node_t
* pl1
,
919 struct bin_pixel_node_t
* pl2
921 { struct bin_pixel_node_t
* pl1p
, * pl2p
;
922 int i
, pl1_len
, pl2_len
;
926 pl1_len
= bin_pixel_list_len(pl1
);
927 pl2_len
= bin_pixel_list_len(pl2
);
929 if (pl1_len
> pl2_len
)
931 else if (pl1_len
< pl2_len
)
933 /* pl1 == pl2, make sure that all refs are the same */
934 /* TODO: what type of warning/error handling should occur here? */
935 for (i
= 0; i
< pl1_len
; i
++)
936 { if (pl1p
->data
.ref
!= pl2p
->data
.ref
)
937 eprintf("Error in determining default pixel list\n");
941 return pl1
; //doesnt matter which one you return
944 /* Find default framebox, based on the framebox with the most attachments*/
945 /* Search through first frame of S of each framebox */
946 struct bin_pixel_node_t
*
947 bin_find_default_pixel_list
950 struct bin_pixel_node_t
* default_pixel_list
, * curr_pixel_list
;
953 struct bin_img_info_t img_info
;
955 for (fiter
= ir_set_framebox(set
); fiter
!= NULL
; fiter
= ir_setdata_nextsib(fiter
))
956 { /* TODO: Stringify the frame name with .png? */
957 /* TODO: Add directory changing */
958 data
= stbi_load(ir_setdata_name((ir_setdata
) ir_framebox_mapsheet(fiter
,SFACE
) ), &img_info
.width
, &img_info
.width
, &num_channels
, 0);
959 bin_set_img_info(&img_info
, ir_framebox_mapsheet(fiter
, SFACE
));
960 curr_pixel_list
= bin_mapframe_to_pixel_list(&img_info
, 0, 0, data
);
961 default_pixel_list
= bin_cmp_default_pixel_lists(curr_pixel_list
, default_pixel_list
);
966 return default_pixel_list
;