more binaryout
[henge/apc.git] / src / binaryout.c
index 8627be6..39ece40 100644 (file)
 #include <unistr.h>   //u32_cpy
 #include <unistdio.h> //ulc_fprintf
 /* Local */
-#define  eprintf_callback(...) exit(EXIT_FAILURE)
 #include "print.h"
 #include "apc.h"
 #include "ir.h"
 #include "pagenode.h"
+#undef  do_error
+#define do_error(...) exit(-1)
 #define XXH_PRIVATE_API
 #include "../xxHash/xxhash.h"
 #define STB_IMAGE_IMPLEMENTATION
@@ -43,11 +44,17 @@ struct bin_img_info_t {
 struct bin_ht_header_t {
   long start;
   int entries;
+  int size;
 };
-struct bin_ht_entry_t {
+struct bin_default_ht_entry_t {
   uint32_t key; 
   long value;
 };
+struct bin_var_ht_entry_t {
+  uint32_t key;
+  long vvalue;
+  long mvalue;
+};
 struct bin_class_header_t {
   struct bin_ht_header_t child_ht;
   struct bin_ht_header_t rootset_ht;
@@ -74,7 +81,7 @@ struct bin_frame_header_t {
 };
 
 struct bin_pixel_t {
-  int x, y, z; 
+  int x, y, z, num; //the x matching pixel 
   uint32_t ref;
   int attach_idx;
 };
@@ -98,6 +105,22 @@ struct bin_attachment_list_t {
   struct bin_attachment_t** attachments;
   long filepos;
 }; 
+struct bin_linklist_t;
+struct bin_linklist_t 
+{ struct bin_linklist_t* next;
+  linkdata               linkdata;
+};
+
+struct bin_processed_links_t
+{ struct bin_linklist_t* vlink_list;
+  int                    vlink_len;
+  struct bin_linklist_t* mlink_list;
+  int                    mlink_len;
+  struct bin_linklist_t* olink_list; //keep track of olink cycles
+  int                    olink_len;
+  struct bin_linklist_t* dlink_list;
+  int                    dlink_len;
+};
 
 struct bin_attachment_list_t **attachment_stack, **asp; //attachment_stack, attachment_stack_pointer
 FILE* binaryout;
@@ -168,7 +191,7 @@ int bin_keys_identical
 }
 
 
-typedef RGBA_t uint32_t;
+typedef uint32_t RGBA_t;
 
 long bin_traverse_class(ir_class);
 /* Takes root class and begins processing */
@@ -178,26 +201,28 @@ ir_binout_init(ir_class root_class)
   asp = attachment_stack;
   pagelist_init(datapages, (size_t) SYS_PAGESIZE);
   pagelist_init(linkpages, (size_t) SYS_PAGESIZE);
+  pagelist_init(plinkpages, (size_t) SYS_PAGESIZE);
   bin_traverse_class(root_class);
 }
 
-#define ENTRY_OCCUPIED() (bytes_null(sizeof(ht_entry->key), entry_pos))
-#define WRITE_ENTRY() do {                             \
-      if(fseek(binaryout, entry_pos, SEEK_SET) == -1) wprintf("fseek failed with %s", strerror(errno)); \
-      fwrite(&ht_entry, sizeof ht_entry, 1, binaryout);        \
-  } while (0)
+
+/* Returns the key position where the hash table entry was inserted. */
+#define ENTRY_OCCUPIED() (bytes_null(uint32_t), entry_pos))
 #define LOOP_ENTRY(_HTSTART) (entry_pos = _HTSTART)
-#define INC_ENTRY() do { \
-      entry_pos += sizeof(ht_entry);           \
-      if(fseek(binaryout, entry_pos, SEEK_SET) == -1) eprintf("fseek failed with %s", strerror(errno)); \
+#define WRITE_DEF_ENTRY() do {                                         \
+    if(fseek(binaryout, entry_pos, SEEK_SET) == -1) wprintf("fseek failed with %s", strerror(errno)); \
+    fwrite(&def_ht_entry, sizeof def_ht_entry, 1, binaryout);          \
+  } while (0)
+#define INC_DEF_ENTRY() do { \
+    entry_pos += sizeof(def_ht_entry);                                 \
+    if(fseek(binaryout, entry_pos, SEEK_SET) == -1) eprintf("fseek failed with %s", strerror(errno)); \
   } while (0)
 #define HT_END(_HTEND) (entry_pos >= _HTEND) //just in case at last entry
 long
-/* TODO: Should overwrite be a default? */
-bin_insert_ht_entry
+bin_insert_default_ht_entry
 ( long ht_start,
-  long ht_size,
-  struct bin_ht_entry_t* ht_entry,
+  int ht_size,
+  struct bin_def_ht_entry_t* def_ht_entry,
   int overwrite
 )
 { long entry_pos, ht_end;
@@ -208,7 +233,7 @@ bin_insert_ht_entry
   
   if (!ENTRY_OCCUPIED())
     { uprintf("key not occupied\n");
-      WRITE_ENTRY();
+      WRITE_DEF_ENTRY();
     }
   while( ENTRY_OCCUPIED() )
     { if(overwrite)
@@ -221,13 +246,67 @@ bin_insert_ht_entry
       if (HT_END(ht_end))
        LOOP_ENTRY(ht_start);
       else 
-       INC_ENTRY();
+       INC_DEF_ENTRY();
     }
-  WRITE_ENTRY();
+  WRITE_DEF_ENTRY();
 
   return entry_pos;
     
 }
+long
+#define WRITE_VAR_ENTRY() do { \
+   if(fseek(binaryout, entry_pos, SEEK_SET) == -1) wprintf("fseek failed with %s", strerror(errno)); \
+   fwrite(&var_ht_entry, sizeof var_ht_entry, 1, binaryout);   \
+} while (0)
+#define INC_VAR_ENTRY() do { \
+    entry_pos += sizeof(var_ht_entry);                                 \
+    if(fseek(binaryout, entry_pos, SEEK_SET) == -1) eprintf("fseek failed with %s", strerror(errno)); \
+  } while (0)
+bin_insert_var_ht_entry
+( long ht_start,
+  int ht_size,
+  struct bin_var_ht_entry_t* var_ht_entry,
+  int overwrite
+)
+{ long entry_pos, ht_end;
+
+  ht_end = ht_start + ht_size; 
+  entry_pos = ht_start + sizeof(var_ht_entry) * ht_entry->key;
+  fseek(binaryout, entry_pos, SEEK_SET);
+  
+  if (!ENTRY_OCCUPIED())
+    { uprintf("key not occupied\n");
+      WRITE_VAR_ENTRY();
+    }
+  while( ENTRY_OCCUPIED() )
+    { if(overwrite)
+       { if(bin_keys_identical(entry_pos, ht_entry->key))
+           break;      
+         else 
+          { eprintf("error in hashtable insertion, keys are identical");
+          }
+       }
+      if (HT_END(ht_end))
+       LOOP_ENTRY(ht_start);
+      else 
+       INC_VAR_ENTRY();
+    }
+  WRITE_VAR_ENTRY();
+
+  return entry_pos;
+
+/** @see http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 */
+static inline
+int bin_calculate_ht_entries
+( int entries )
+{ entries = (entries << 1) - 1;
+  entries |= entries >> 1;
+  entries |= entries >> 2;
+  entries |= entries >> 4;
+  entries |= entries >> 8;
+  entries |= entries >> 16;
+  return ++entries;
+}
 
 /* |     class header   |
    |--------------------|
@@ -243,8 +322,13 @@ bin_insert_ht_entry
 
 long bin_traverse_set(ir_set);
 long
-#define HT_INIT(_START,  _SIZE, _INIT_ENTRIES) do {       \
-  _SIZE = _INIT_ENTRIES ? (_INIT_ENTRIES * (sizeof(struct bin_ht_entry_t) << 1)): 0; \
+#define DEF_HT_INIT(_START,  _SIZE, _INIT_ENTRIES) do {                \
+  _SIZE = _ENTRIES * sizeof(var_ht_entry); \
+  _START = ftell(binaryout); \
+  fseek(binaryout, _SIZE, SEEK_CUR); \
+} while (0)
+#define VAR_HT_INIT(_START, _SIZE, _ENTRIES) do { \
+  _SIZE = _ENTRIES * sizeof(var_ht_entry);       \
   _START = ftell(binaryout); \
   fseek(binaryout, _SIZE, SEEK_CUR); \
 } while (0)
@@ -253,30 +337,32 @@ bin_traverse_class
 { ir_class citer;
   ir_set siter;
   struct bin_class_header_t class_header;
-  struct bin_ht_entry_t ht_entry;
+  struct bin_def_ht_entry_t ht_entry;
   long class_start, classht_start, classht_size, rootsetht_start, rootsetht_size;
-  int num_csibs, num_ssibs;
+  int num_class_entries, num_rootset_entries;
   uint8_t* class_name;
 
   class_start = ftell(binaryout);
   class_name = ir_class_name(class);
 
-  num_csibs = bin_class_sibcount(class);
-  num_ssibs = bin_set_sibcount(ir_class_rootset(class));
+  num_class_entries = bin_calculate_ht_entries(bin_class_sibcount(class));
+  num_rootset_entries = bin_calculate_ht_entries(ir_class_rootset(class));
 
   /* alloc space (before hash tables) for class header */
   class_header.namelen = u8_strlen(class_name);
   fseek(binaryout, class_start + sizeof(class_header) + class_header.namelen ,SEEK_SET);
   
-  HT_INIT(classht_start, classht_size, num_csibs);
-  HT_INIT(rootsetht_start, rootsetht_size, num_ssibs);
+  DEF_HT_INIT(classht_start, classht_size, num_class_entries);
+  DEF_HT_INIT(rootsetht_start, rootsetht_size, num_rootset_entries);
   
   /* TODO: Figure out generic way to output headers */
   /* populate class header */
-  class_header.child_ht.entries = num_csibs;
+  class_header.child_ht.entries = num_class_entries;
   class_header.child_ht.start = classht_start;
-  class_header.rootset_ht.entries = num_ssibs;
+  class_header.child_ht.size = classht_size;
+  class_header.rootset_ht.entries = num_rootset_entries;
   class_header.rootset_ht.start = rootsetht_start;
+  class_header.rootset_ht.size = rootsetht_size;
   fseek(binaryout, class_start, SEEK_SET); //seek back to where we allocated header
   fwrite(&class_header, sizeof(class_header), 1, binaryout);
   fwrite(class_name, class_header.namelen, 1, binaryout);
@@ -284,9 +370,9 @@ bin_traverse_class
   /* Start populating root_set hash table */
   for ( siter = ir_class_rootset(class); siter != NULL; siter = ir_set_nextsib(siter))
     { fseek(binaryout, 0, SEEK_END);
-      ht_entry.key = NAMEHASH(ir_set_name(siter), num_ssibs << 1);
+      ht_entry.key = NAMEHASH(ir_set_name(siter), num_rootset_entries);
       ht_entry.value = bin_traverse_set(siter);
-      bin_insert_ht_entry(rootsetht_start, rootsetht_size, &ht_entry, 0);      
+      bin_insert_def_ht_entry(rootsetht_start, rootsetht_size, &ht_entry, 0);      
     }
 
   /* Start populating class child hash table */
@@ -294,9 +380,9 @@ bin_traverse_class
     { if(chdir((char*) class_name))
        eprintf("CHDIR %U from %s\n",(char*) class_name,getcwd(NULL,255));
       fseek(binaryout, 0, SEEK_END);
-      ht_entry.key = NAMEHASH(ir_class_name(citer), num_csibs << 1);     
+      ht_entry.key = NAMEHASH(ir_class_name(citer), num_class_entries);     
       ht_entry.value = bin_traverse_class(citer);
-      bin_insert_ht_entry(classht_start, classht_size, &ht_entry, 0);
+      bin_insert_def_ht_entry(classht_start, classht_size, &ht_entry, 0);
       if (chdir(".."))
        eprintf("CHDIR ..\n");
     }
@@ -321,8 +407,8 @@ bin_traverse_set
 ( ir_set set )
 { ir_set iter;
   struct bin_set_header_t header;
-  struct bin_ht_entry_t ht_entry;
-  int num_child, setname_len;
+  struct bin_def_ht_entry_t ht_entry;
+  int num_entries, setname_len;
   long childht_start, childht_size, set_start;
   uint8_t* set_name;
 
@@ -337,21 +423,23 @@ bin_traverse_set
   header.sdat_start = bin_process_sdat(set);
 
   /* Setup child hash table for current sets children */
-  num_child = bin_set_sibcount(ir_set_nextchild(set));
-  HT_INIT(childht_start, childht_size, num_child);
+  num_entries = bin_calculate_ht_entries(bin_set_sibcount(ir_set_nextchild(set)));
+  
+  DEF_HT_INIT(childht_start, childht_size, num_child);
 
   /* populate header, write to file */
-  header.child_ht.entries = num_child;
+  header.child_ht.entries = num_entries;
   header.child_ht.start = childht_start;
+  header.child_ht.size = childht_size;
   fseek(binaryout, set_start, SEEK_SET);
   fwrite(&header, sizeof(struct bin_set_header_t), 1, binaryout);
   fwrite(set_name, setname_len, 1, binaryout);
 
   for(iter = ir_set_nextchild(set); iter != NULL; iter = ir_set_nextsib(iter))
     { fseek(binaryout, 0, SEEK_END);
-      ht_entry.key = NAMEHASH(ir_set_name(iter), num_child << 1);
+      ht_entry.key = NAMEHASH(ir_set_name(iter), num_entries);
       ht_entry.value = bin_traverse_set(iter);
-      bin_insert_ht_entry(childht_start, childht_size, &ht_entry, 0);      
+      bin_insert_def_ht_entry(childht_start, childht_size, &ht_entry, 0);      
     }
   
 
@@ -377,11 +465,11 @@ bin_traverse_set
  
 */
 
-void bin_insert_links(struct bin_processed_lists_t*, struct bin_ht_header_t*, long);
-struct bin_pixel_node_t* bin_find_default_pixel_list(ir_set);
-void bin_process_frameboxes(ir_set, struct bin_ht_header_t*, struct bin_pixel_node_t*);
-int bin_process_links(ir_set, ir_setdata);
-int bin_process_dlinks(struct bin_processed_lists_t*);
+static inline void bin_insert_links(struct bin_processed_links_t*, struct bin_ht_header_t*, long);
+static inline struct bin_pixel_node_t* bin_find_default_pixel_list(ir_set);
+static inline void bin_process_frameboxes(ir_set, struct bin_ht_header_t*, struct bin_pixel_node_t*);
+static inline struct bin_processed_links_t* bin_process_links(ir_set, struct bin_processed_links_t*);
+static inline void bin_process_dlinks(struct bin_processed_links_t*);
 
 /* Init the variant hash table for the set, process the sets links and add them to link_stack
    and variant hash table, and then output the actual framedata */
@@ -402,28 +490,28 @@ bin_process_sdat
   fseek(binaryout, sizeof(struct bin_setdata_header_t), SEEK_CUR);
 
   /* set up root for processed_links */
-  processed_links_root = stack_alloc(&plinkpages, bin_processed_links_t);
-  processed_links_root_val->mlink_len = processed_links_root->vlink_len = 0;
-  processed_links_root =  bin_process_links(set, processed_links_root);
+  processed_links_root = stack_alloc(&plinkpages, sizeof(struct bin_processed_links_t));
+  processed_links_root->mlink_len = processed_links_root->vlink_len = processed_links_root->dlink_len = processed_links_root->olinks_len = 0;
+  processed_links_root = bin_process_links(set, processed_links_root);
 
   num_links = processed_links_root->mlink_len + processed_links_root->vlink_len;
   
-  num_entries = bin_set_varcount(set) + num_links;
+  num_entries = bin_calculate_ht_entries(bin_set_varcount(set) + num_links);
   
-  HT_INIT(varht_start, varht_size, num_entries);
+  VAR_HT_INIT(varht_start, varht_size, num_entries);
 
   /* Populate the sdat_header */
   fseek(binaryout, 0, sdat_start);
-  header.variant_ht.start = ht_header.start = varht_start;
-  header.variant_ht.entries = ht_header.entries = num_entries;
+  header.variant_ht.start =  varht_start;
+  header.variant_ht.entries = num_entries;
+  header.variant_ht.size = varht_size;
   attachment_list.filepos = header.attach_pos = ftell(binaryout) + sizeof(varht_start) + sizeof(num_entries);
   fwrite(&header, sizeof(header), 1, binaryout);
-  fseek(binaryout, 0, SEEK_END);
+  fseek(binaryout, 0, SEEK_ENDhttps://en.wikipedia.org/wiki/Generic_programming);
 
   /* Process dlinks */
   bin_process_dlinks(processed_links_root);
   
-  
   /* Determine the default pixel list for all of the frameboxes */
   default_pixel_list = bin_find_default_pixel_list(set);
   /* Output each framebox, and insert it into the variant hash table */
@@ -434,8 +522,8 @@ bin_process_sdat
 
   /* TODO: Convert the default pixel list to an attachment_list and then push the  */
   /*       sdats attachment_list onto the attachment_stack so it can be procesed   */
+  
 
-  /* free plinkpages and datapages */
 
 
   return sdat_start;
@@ -443,10 +531,10 @@ bin_process_sdat
 static inline
 void bin_process_dlinks
 ( struct bin_processed_links_t* processed_links )
-{ struct bin_linklist_t* olink_iter;
-  ir_set trg_set;
+{ struct bin_linklist_t* dlink_iter;
   for( dlink_iter = processed_links->dlink_list; dlink_iter != NULL; dlink_iter = dlink_iter->next)
-    { /* Construct its fully qualified name based on ?*/
+    { /* TODO: Construct its fully qualified name based on its linkdata*/
+      
       /* Output an int for its length, and then output the name */
           
          
@@ -471,7 +559,7 @@ void
 bin_process_vlink
 ( linkdata vlink,
   struct bin_processed_links_t* processed_links)
-{ struct bin_processed_links_t* plp;
+{ struct bin_linklist_t* llp;
   struct bin_linklist_t* vlink_list_head;
   linkdata new_vlink;
   ir_setdata fiter;
@@ -481,53 +569,72 @@ bin_process_vlink
   vlink_list_head = bin_linklist_head(processed_links->vlink_list);
   link_name = ir_setdata_name(vlink); 
   if (link_name) 
-    { plp =  struct_alloc(bin_processed_links_t);
-      plp->linkdata = vlink;
-      vlink_list_head->next = plp;
+    { llp =  stack_alloc(&plinkpages, sizeof(bin_linklist_t));
+      llp->linkdata = vlink;
+      vlink_list_head->next = llp;
       processed_links->vlink_len++;
-      PUSH_LINK(vlink);
     }
   else // linking a variant hash table
     { trg_set = ir_linkdata_set(vlink);
       for (fiter = ir_set_framebox(trg_set); fiter != NULL; fiter = ir_setdata_nextsib(fiter))
-      { plp = struct_alloc(bin_processed_links_t);
-        new_vlink = struct_alloc(linkdata);
-       ir_linkdata_assign_name(new_vlink,ir_setdata_name(fiter));
-       ir_linkdata_assign_set(new_vlink,trg_set);
-       ir_linkdata_assign_type(new_vlink,VLINK);
-        plp->linkdata = vlink;
-        vlink_list_head->next = plp;
-        processed_links->vlink_len++;
-        PUSH_LINK(vlink);
-      }
+       { llp = stack_alloc(&plinkpages, sizeof(bin_linklist_t));
+         new_vlink = stack_alloc(&plinkpages, sizeof(linkdata));
+         ir_data_assign_path(new_vlink,ir_setdata_name(fiter));
+         ir_linkdata_assign_set(new_vlink,trg_set);
+         ir_linkdata_assign_type(new_vlink,VLINK);
+         llp->linkdata = vlink;
+         vlink_list_head->next = llp;
+         processed_links->vlink_len++;
+       }
     }
 
-  return processed_links;
 
 }
 
 /* Adds an mlink to the stack_alloc, to be processed later */
+/* TODO: redo */
 void
 bin_process_mlink
 ( linkdata mlink,
-  bin_processed_links_t* processed_links
+  struct bin_processed_links_t* processed_links
 )
 { uint8_t* mlink_name;
-  struct bin_processed_links_t* mlink_list_head;
+  struct bin_linklist_t* llp;
+  struct bin_linklist_t* mlink_list_head;
+  linkdata new_mlink;
+  ir_setdata fiter;
+  ir_set trg_set;
+  
 
-  mlink_list_head = bin_listlist_head(processed_links->mlink_list);
+  mlink_list_head = bin_linklist_head(processed_links->mlink_list);
   mlink_name = ir_setdata_name(mlink);
-  plp = stack_alloc(&linkpages, bin_linklist_t);
-  plp->header.filepos = 0; //TBD after resolving the childlist | TODO: attach_pos?
-  if(mlink_name) plp->name = mlink_name;// TODO: What does a mlink with a name mean? specifying the framebox mapsheet to use? 
-  plp->trg_set = ir_linkdata_set(mlink);
-  mlink_list_head->next = plp;
-  processed_links->mlink_len++;
+
+  if(mlink_name) 
+    { llp =  stack_alloc(&plinkpages, sizeof(bin_linklist_t));
+      llp->linkdata = mlink;
+      mlink_list_head->next = llp;
+      processed_links->mlink_len++;
+    }
+  else
+    { trg_set = ir_linkdata_set(mlink);
+      for (fiter = ir_set_framebox(trg_set); fiter != NULL; fiter = ir_setdata_nextsib(fiter))
+       { //TODO: check here if illegal mlink(linking to a opsheet of a vdat not in src_set domain)? 
+         llp = stack_alloc(&plinkpages, sizeof(bin_linklist_t));
+         new_mlink = stack_alloc(&plinkpages, sizeof(linkdata));
+         ir_data_assign_path(new_mlink,ir_setdata_name(fiter));//TODO: assign name
+         ir_linkdata_assign_set(new_vlink,trg_set);
+         ir_linkdata_assign_type(new_vlink,VLINK);
+         llp->linkdata = vlink;
+         vlink_list_head->next = llp;
+         processed_links->vlink_len++;
+       }
+    }
+
+  
 
   return processed_links;
 }
 
-/* TODO: implement this */
 /* Determine if olink is already part of the olink_list. 
    if it is, theres a cycle, return 1. Else return 0. */
 static inline
@@ -539,7 +646,7 @@ int olink_cycle
   ir_set olink_set;
   olink_set = ir_linkdata_set(olink);
   for( iter = processed_links->olink_list; iter != NULL; iter = iter->next)
-    if(iter == olink_set)
+    if(ir_linkdata_set(iter->linkdata) == olink_set)
      return 1;  
   
   return 0;
@@ -548,53 +655,39 @@ int olink_cycle
    else its a dlink so just add it to the processed_links list*/
 static inline
 void bin_process_olink
-( linkdata olink,
-  struct bin_processed_links_t* processed_links_root,
-  ir_set trg_set
+( ir_set trg_set,
+  linkdata olink,
+  struct bin_processed_links_t* processed_links_root 
 )
 { struct bin_linklist_t* link_list_head;
-  if(trg_set)) //add olink to list so we can check for cycles
-    { bin_set_frameboxes_vlinks(trg_set, processed_links_root); //TODO: implement
-      bin_set_attachmentlist_mlink(trg_set, processed_links_root); //TODO: implement
+  struct bin_linklist_t* new_link;
+
+  new_link = stack_alloc(&plinkpages, sizeof(bin_linklist_t));
+  if(trg_set) //add olink to list so we can check for cycles
+    { bin_set_frameboxes_vlinks(trg_set, processed_links_root); //TODO: 
+      bin_set_attachmentlist_mlink(trg_set, processed_links_root); //TODO: 
       link_list_head = bin_linklist_head(processed_links_root->olink_list);
-      link_list_head->next = struct_alloc(bin_linklist_t);
-      link_list_head->next->linkdata = olink;
+      new_link->linkdata = olink;
+      link_list_head->next = new_link;
     }
   else // olink is actually a dynamic link
     { link_list_head = bin_linklist_head(processed_links_root->dlink_list);
-      link_list_head->next = struct_alloc(bin_linklist_t);
-      link_list_head->next->linkdata = olink;
+      new_link->linkdata = olink;
+      link_list_head->next = new_link;
     }
   
 }
 
-struct bin_linklist_t;
-struct bin_linklist_t 
-{ struct bin_linklist_t* next;
-  linkdata               linkdata;
-};
-
-struct bin_processed_links_t
-{ struct bin_linklist_t* vlink_list;
-  int                    vlink_len;
-  struct bin_linklist_t* mlink_list;
-  int                    mlink_len;
-  struct bin_linklist_t* olink_list; //keep track of olink cycles
-  int                    olink_len;
-  struct bin_linklist_t* dlink_list;
-  int                    dlink_len;
-};
 
 /* Given a set, determine the number of links it has and process each link and 
    then add them to stack_alloc, where they will be popped off and further processed. */
 struct bin_processed_links_t* bin_process_links
 ( ir_set src_set,
-  struct bin_processed_links_t* processed_links_root;
+  struct bin_processed_links_t* processed_links_root
 )
-{ struct bin_processed_links_t* returned_val;
-  linkdata linkdata;
+{ linkdata linkdata;
   ir_set trg_set;
-  for(linkdata = ir_set_link(src_set); linkdata != NULL; linkdata = (linkdata) ir_setdata_nextsib((ir_setdata) linkdata))
+  for(linkdata = ir_set_link(src_set); linkdata != NULL; linkdata = ir_setdata_nextsib((ir_setdata) linkdata))
     { switch (ir_linkdata_type(linkdata)) {
       case OLINK:
        if (olink_cycle(linkdata, processed_links_root)) 
@@ -617,8 +710,10 @@ struct bin_processed_links_t* bin_process_links
 }
 
 /* Insert both mlinks and vlinks into the link stack, after determining their src_pos. Vlinks 
-   have an additional requirement of being added into the variant hash table */ 
-#define PUSH_PLINK(_LINK) (*(struct **) stack_alloc(&linkpages, sizeof (_LINK)) = _LINK )
+   have an additional requirement of being added into the variant hash table */
+#define FRAME_POS() (entry_pos + sizeof(long))
+#define MAP_POS()   (entry_pos + sizeof(long)*2)
+#define PUSH_PLINK(_LINK) (*(linkdata*) stack_alloc(&linkpages, sizeof (_LINK)) = _LINK )
 void
 bin_insert_links
 ( struct bin_processed_links_t* links,
@@ -626,25 +721,29 @@ bin_insert_links
   long attach_pos
 )
 { struct bin_plink_t* plp;
-  struct bin_ht_entry_t ht_entry;
-  struct link_list_t* vlinkiter, mlinkiter;
+  struct bin_var_ht_entry_t ht_entry;
+  struct bin_linklist_t* vlinkiter, *mlinkiter;
   long entry_pos;
   
   
-  /* Insert vlinks into hash table, put v/mlinks on link stack to be processed later */
-  for ( vlinkiter = links->vlink_root; vlinkiter != NULL; vlinkiter = vlinkiter->next;)
-    { ht_entry.key = NAMEHASH(ir_setdata_name(vlinkiter->linkdata), ht->entries << 1);
-      ht_entry.value = 0;
-      entry_pos = bin_insert_ht_entry(ht->start, ht->entries * sizeof(ht_entry), &ht_entry, 0);     
-      ir_setdata_assign_fpos(vlinkiter->linkdata, entry_pos);
+  /* Insert vlinks and mlinks into hash table, put v/mlinks on link stack to be processed later */
+  for ( vlinkiter = links->vlink_list; vlinkiter != NULL; vlinkiter = vlinkiter->next)
+    { ht_entry.key = NAMEHASH(ir_setdata_name(vlinkiter->linkdata), ht->entries);
+      ht_entry.fvalue = 0;
+      entry_pos = bin_insert_var_ht_entry(ht->start, ht->size, &ht_entry, 0);     
+      ir_setdata_assign_fpos(vlinkiter->linkdata, FRAME_POS());
       PUSH_PLINK(vlinkiter->linkdata);
     }
-  for ( mlinkiter = links->mlink_root; mlinkiter != NULL; mlinkiter = mlinkiter->next)
-    { >trg_set = plp->trg_set;
-      plp->src_pos = attach_pos;
-      PUSH_PLINK(plp);
+  /* TODO: If name exists in src_set, overwrite. if it dont, print a warning */
+  for ( mlinkiter = links->mlink_list; mlinkiter != NULL; mlinkiter = mlinkiter->next)
+    { ht_entry.key = NAMEHASH(ir_setdata_name(mlinkiter->linkdata), ht->size);
+      ht_entry.mvalue = 0;
+      entrypos = bin_insert_var_ht_entry(ht->start, ht->size, &ht_entry, 0);
+      ir_setdata_assign_fpos(mlinkiter->linkdata, MAP_POS());
+      PUSH_PLINK(mlinkiter->linkdata);
     }
-  /* Process dlinks here */
+  /* free all the processed links */
+  pagelist_free(plinkpages);
 
      
 }
@@ -698,9 +797,9 @@ bin_process_frameboxes
   /* Insert variants into hash table to overwrite olink insertions*/
   for ( fiter = ir_set_framebox(set); fiter != NULL; fiter = ir_setdata_nextsib(fiter))
     { fseek(binaryout, 0, SEEK_END);
-      ht_entry.key = NAMEHASH(ir_setdata_name(fiter), ht->entries << 1);  
+      ht_entry.key = NAMEHASH(ir_setdata_name(fiter), ht->entries);  
       ht_entry.value = bin_process_framebox(set, fiter, default_pixel_list);
-      bin_insert_ht_entry(ht->start, ht->entries * sizeof(ht_entry), &ht_entry, 1);     
+      bin_insert_var_ht_entry(ht->start, ht->entries * sizeof(ht_entry), &ht_entry, 1);     
     }
 
 }
@@ -727,6 +826,7 @@ void bin_set_img_info
    |-----------------------------| */
 
 long
+//TODO: THIS SHOULD THE SET SPEC, NOT THE FRAMEBOX NAME
 #define GENERATE_FILENAME(_N) ((char*) u8_strcat(_N, png_suffix))
 bin_process_facing
 ( ir_setdata framebox,
@@ -767,26 +867,30 @@ bin_process_facing
   fwrite(&header, sizeof(header), 1, binaryout);
   fseek(binaryout, 0, SEEK_END);
 
+  
+
  
   /* Assuming that fheight = image height */
   /* For each mapframe in mapsheet */
   for ( x = 0; x < header.frames; x++)
-    { map_pixel_list = bin_map_to_pixel_list(mapsheet_info, 0, x * mapsheet_info.fwidth, data);
+    { map_pixel_list = bin_mapframe_to_pixel_list(mapsheet_info, 0, x * mapsheet_info.fwidth, mapdata);
       if(!bin_process_map_pixel_list(default_pixel_list, map_pixel_list))
         eprintf("error processing map pixel list\n");
       bin_output_pixel_list(map_pixel_list);
-      data += mapsheet_info.fwidth;
+      mapdata = mapsheet_info.fwidth * x; //do we do this in mapframe to pixellist?
 
     }
-    /* Determine pixel_list */
-
-    /* Output pixel_list */
   
  
   return facing_start;
   
 }
 
+/* pixel_list == ops, output up to fwidth amount of them */
+void
+bin_output_pixel_list(struct bin_pixel_node_t* map_pixel_list)
+
 /* TODO: Please rename all the functions jhc*/
 static inline
 void bin_number_pixel_list
@@ -794,7 +898,7 @@ void bin_number_pixel_list
 { int num = 0;
   struct bin_pixel_node_t* iter;
   while (iter)
-    { iter.data.attach_idx = num++;
+    { iter->data.attach_idx = num++;
       iter = iter->next;
     }
 }
@@ -827,15 +931,13 @@ int bin_valid_map_pixel_list
 ( struct bin_pixel_node_t* default_pixel_list,
   struct bin_pixel_node_t* map_pixel_list
 )
-{ struct bin_pixel_node_t* mapiter, defaultiter;
+{ struct bin_pixel_node_t* mapiter, *defaultiter;
   defaultiter = default_pixel_list;
   /* check length of each to make sure default < max */
   /* for each pixel node in default and map */
-  while(defaultiter)
-    { for( mapiter = map_pixel_list; mapiter != NULL; mapiter = mapiter->next)
-       { 
-       }
-    }
+  /* TODO: Implement:: basically just checkking if map_pixel_list is subset of default_pixel_list
+     which means is the intersection of default_pl and map_pl == default_pl */
+  
 
 
   if(!mapiter && defaultiter) //defaultiter is longer so error!
@@ -852,9 +954,12 @@ int bin_process_map_pixel_list
   struct bin_pixel_node_t* map_pixel_list
 )
 { /* Determine if pixel_list is valid */
-   
+  if(!bin_valid_map_pixel_list(default_pixel_list, map_pixel_list))
+    return 0;
+                              
   /* Determine attach_idx of each pixel, as compared to default pixel list */
   
+  
 }
 
 void
@@ -889,11 +994,17 @@ bin_insert_node_into_list
              break;
            }
        }
-      else if (pixel_node->data.z < head_node->data.z || pixel_node->data.z == head_node->data.z)
-       { prev_node->next = pixel_node;
+      else if (pixel_node->data.z < head_node->data.z)
+       { pixel_node->num++;
+         prev_node->next = pixel_node;
          pixel_node->next = head_node;
          break;
        }
+      else // pixel_node->data.z == head_node->data.z
+       { pixel_node->num = head_node->num + 1;
+         prev_node->next = pixel_node;
+         pixel_node->next = head_node;
+       }
     }
 
   return pixel_list_root;
@@ -935,7 +1046,7 @@ bin_mapframe_to_pixel_list
     
   
   /* Process the map*/
-  for (y = 0; y < fheight; y++)
+  for (y = 0; y < fheight ; y++)
     { for ( x = 0; x < fwidth; x++ )
       { if (*data)
          { pixel_node = struct_alloc(bin_pixel_node_t);
@@ -950,8 +1061,24 @@ bin_mapframe_to_pixel_list
          }
        data++;
       }
-      data += img_info->width - img_info->fwidth; //stride
+      data += img_info->width - img_info->fwidth; //stride TODO: isnt this null at the last iteration?
     }
+  //TODO: fix these two for loops why dontcha
+  for ( x = 0; x < fwidth; x++ )
+    { if (*data)
+       { pixel_node = struct_alloc(bin_pixel_node_t);
+         /* get ref from 4 bytes of data */  
+         pixel_node->data.ref =  (*data) >> 8;
+         /* bitshift by ? to get Z */
+         pixel_node->data.z = (*data & 0xFF);
+         /* set x and y */
+         pixel_node->data.x = x + init_width;
+         pixel_node->data.y = y + init_width;
+         pixel_list = bin_insert_node_into_list(pixel_list, pixel_node);
+       }
+      data++;
+    }
+  
   return pixel_list;
 }