more binaryout changes
authorJordan <jordanlavatai@gmail.com>
Fri, 17 Feb 2017 00:47:01 +0000 (16:47 -0800)
committerJordan <jordanlavatai@gmail.com>
Fri, 17 Feb 2017 00:47:01 +0000 (16:47 -0800)
src/binaryout.c

index ee82c6f..ffb4021 100644 (file)
@@ -19,7 +19,9 @@
 #define XXH_PRIVATE_API
 #include "../xxHash/xxhash.h"
 #define STB_IMAGE_IMPLEMENTATION
-#include "stb_image.h"
+#include "../stb/stb_image.h"
+#define STB_IMAGE_WRITE_IMPLEMENTATION
+#include "../stb/stb_image_write.h"
 
 /* Public */
 void ir_binout_init(struct ir_class_t*);
@@ -80,22 +82,18 @@ struct bin_plink_t {
 struct bin_pixel_t {
   int x, y, z; 
   uint32_t ref;
+  int attach_idx;
 };
 struct bin_pixel_node_t {
   struct bin_pixel_node_t* next;
   struct bin_pixel_t data;
 };
-struct bin_op_t {
-  int x;
-  int y;
-  int attach_idx;
-};
 struct bin_attachment_header_t {
   int num_attachment_lists;
   int num_attachments;
 };
 struct bin_attachment_t {
-  int idx;
+  int x, y, z, idx;
   ir_set set;
 };
 /* Read out of the als, after first ir pass, resolves the
@@ -114,6 +112,41 @@ FILE* binaryout;
 
 #define  NAMEHASH(name, domain) (XXH32(name, u8_strlen(name), 0XCEED ) & domain) 
 
+static inline
+int bin_set_varcount
+( ir_set set )
+{ int count;
+  framebox set_fb;
+  framebox iter;
+  set_fb = ir_set_framebox(set);
+  count = 0;
+  for (iter = set_fb; iter != NULL; iter = ir_setdata_nextsib(iter))
+    count++;
+  return count;
+}
+
+static inline
+int bin_class_sibcount
+( ir_class class )
+{ int count;
+  ir_class iter;
+  count = 0;
+  for (iter = class; iter != NULL; iter = ir_class_nextsib(iter))
+    count++;
+  return count;
+}
+
+static inline
+int bin_set_sibcount
+( ir_set set )
+{ int count;
+  ir_set iter;
+  count = 0;
+  for (iter = set; iter != NULL; iter = ir_set_nextsib(iter))
+    count++;
+  return count;
+}
+
 /* Given a position and a size, checks if the bytes are null and returns
    the file position to where it started. 1 if not null, 0 if null*/
 /* TODO: Determine why fseeking file past end sets bytes to -1, and not 0 */
@@ -230,10 +263,10 @@ bin_traverse_class
   uint8_t* class_name;
 
   class_start = ftell(binaryout);
-  class_name = get_class_name(class);
+  class_name = ir_class_name(class);
 
-  num_csibs = get_class_sibcount(class);
-  num_ssibs = get_set_sibcount(get_class_root_set(class));
+  num_csibs = bin_class_sibcount(class);
+  num_ssibs = bin_set_sibcount(ir_class_rootset(class));
 
   /* alloc space (before hash tables) for class header */
   class_header.namelen = u8_strlen(class_name);
@@ -253,19 +286,23 @@ bin_traverse_class
   fwrite(class_name, class_header.namelen, 1, binaryout);
  
   /* Start populating root_set hash table */
-  for ( siter = get_class_root_set(class); siter != NULL; siter = get_set_nextsib(siter))
+  for ( siter = ir_class_rootset(class); siter != NULL; siter = ir_set_nextsib(siter))
     { fseek(binaryout, 0, SEEK_END);
-      ht_entry.key = NAMEHASH(get_set_name(siter), num_ssibs << 1);
+      ht_entry.key = NAMEHASH(ir_set_name(siter), num_ssibs << 1);
       ht_entry.value = bin_traverse_set(siter);
       bin_insert_ht_entry(rootsetht_start, rootsetht_size, &ht_entry, 0);      
     }
 
   /* Start populating class child hash table */
-  for ( citer = get_class_nextchild(class); citer != NULL; citer = get_class_nextsib(citer))
-    { fseek(binaryout, 0, SEEK_END);
-      ht_entry.key = NAMEHASH(get_class_name(citer), num_csibs << 1);     
+  for ( citer = ir_class_nextchild(class); citer != NULL; citer = ir_class_nextsib(citer))
+    { 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.value = bin_traverse_class(citer);
       bin_insert_ht_entry(classht_start, classht_size, &ht_entry, 0);
+      if (chdir(".."))
+       eprintf("CHDIR ..\n");
     }
 
   return class_start;
@@ -294,7 +331,7 @@ bin_traverse_set
   uint8_t* set_name;
 
   set_start = ftell(binaryout);
-  set_name = get_set_name(set);
+  set_name = ir_set_name(set);
   
   /* alloc space for set header */
   setname_len = u8_strlen(set_name);
@@ -304,7 +341,7 @@ bin_traverse_set
   header.sdat_start = bin_process_sdat(set);
 
   /* Setup child hash table for current sets children */
-  num_child = get_set_sibcount(get_set_nextchild(set));
+  num_child = bin_set_sibcount(ir_set_nextchild(set));
   HT_INIT(childht_start, childht_size, num_child);
 
   /* populate header, write to file */
@@ -314,15 +351,15 @@ bin_traverse_set
   fwrite(&header, sizeof(struct bin_set_header_t), 1, binaryout);
   fwrite(set_name, setname_len, 1, binaryout);
 
-  for(iter = get_set_nextchild(set); iter != NULL; iter = get_set_nextsib(iter))
+  for(iter = ir_set_nextchild(set); iter != NULL; iter = ir_set_nextsib(iter))
     { fseek(binaryout, 0, SEEK_END);
-      ht_entry.key = NAMEHASH(get_set_name(iter), num_child << 1);
+      ht_entry.key = NAMEHASH(ir_set_name(iter), num_child << 1);
       ht_entry.value = bin_traverse_set(iter);
       bin_insert_ht_entry(childht_start, childht_size, &ht_entry, 0);      
     }
   
 
-  set_set_filepos(set, set_start);
+  ir_set_assign_fpos(set, set_start);
   return set_start;
   
 }
@@ -362,7 +399,7 @@ bin_process_sdat
   fseek(binaryout, sizeof(struct bin_setdata_header_t), SEEK_CUR);
 
   num_links = bin_process_links(set, olink_head);
-  num_entries = get_set_variants(set) + num_links;
+  num_entries = bin_set_varcount(set) + num_links;
   
   HT_INIT(varht_start, varht_size, num_entries);
 
@@ -406,7 +443,7 @@ bin_process_vlink
   num_links = 0;
 
   /* TODO: Macroize? or not worth? */
-  link_name = get_link_name(vlink);
+  link_name = ir_setdata_name(vlink);
   
   if (link_name)
     { plp = struct_alloc(bin_plink_t);
@@ -417,10 +454,10 @@ bin_process_vlink
       num_links++;
     }
   else // linking a variant hash table
-    for (fiter = get_set_frameboxes(trg_set); fiter != NULL; fiter = get_framebox_nextsib(fiter))
+    for (fiter = ir_set_framebox(trg_set); fiter != NULL; fiter = ir_setdata_nextsib(fiter))
       { plp = struct_alloc(bin_plink_t);
        plp->src_pos = 0; // TBD @ process_setdata
-       plp->name = get_framebox_name(fiter);
+       plp->name = ir_setdata_name(fiter);
        plp->trg_set = trg_set;
        plp->type = VLINK;
        num_links++;
@@ -438,7 +475,7 @@ bin_process_mlink
 )
 { struct bin_plink_t* plp;
   uint8_t* mlink_name;
-  mlink_name = get_link_name(mlink);
+  mlink_name = ir_setdata_name(mlink);
   plp = struct_alloc(bin_plink_t);
   plp->src_pos = 0; //TBD after resolving the childlist | TODO: attach_pos?
   if(mlink_name) plp->name = mlink_name;
@@ -472,14 +509,14 @@ bin_process_links
   ir_setdata olink_head
 )
 { int num_links;
-  ir_setdata liter; //link iter
+  linkdata liter; //link iter
   ir_set trg_set;
 
   num_links = 0;
   
-  for(liter = get_set_links(src_set); liter != NULL; liter = get_link_nextsib(liter))
-    { trg_set = get_set_from_ref(get_link_ref(liter));
-      switch (get_link_type(liter)) {
+  for(liter = ir_set_link(src_set); liter != NULL; liter = ir_setdata_nextsib((ir_setdata) liter))
+    { trg_set = ir_set_from_ref(ir_linkdata_ref(liter));
+      switch (ir_linkdata_type(liter)) {
       case OLINK:
        if (olink_cycle(liter, olink_head)) //TODO: stack of olinks to iterate and check for cycles? 
          return num_links;
@@ -587,9 +624,9 @@ bin_process_frameboxes
   ir_setdata fiter;
   
   /* Insert variants into hash table to overwrite olink insertions*/
-  for ( fiter = get_set_frameboxes(set); fiter != NULL; fiter = get_framebox_nextsib(fiter))
+  for ( fiter = ir_set_framebox(set); fiter != NULL; fiter = ir_setdata_nextsib(fiter))
     { fseek(binaryout, 0, SEEK_END);
-      ht_entry.key = NAMEHASH(get_framebox_name(fiter), ht->entries << 1);  
+      ht_entry.key = NAMEHASH(ir_setdata_name(fiter), ht->entries << 1);  
       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);     
     }
@@ -599,103 +636,196 @@ bin_process_frameboxes
 static inline
 void bin_set_img_info
 ( struct bin_img_info_t* img_info,
-  ir_setdata framedata
+  ir_setdata frame_data
 )
-{ img_info->fwidth = get_framedata_width(framedata);
-  img_info->fheight = get_framedata_height(framedata);
+{ ir_frameinfo frameinfo;
+  frameinfo = ir_framedata_frameinfo(frame_data);
+  img_info->fwidth = frameinfo->w;
+  img_info->fheight = frameinfo->h;
   img_info->unaligned_height = img_info->height % img_info->fheight;
   img_info->unaligned_width = img_info->width % img_info->fwidth;
 
 }
+/* |-----------------------------|
+   |        frame header         |
+   |-----------------------------|
+   |  pixel data for frame1 - n  |
+   |-----------------------------|
+   |  op data for frame1 - n     |
+   |-----------------------------| */
 
-/* TODO: Implement this */
-long
-bin_process_frame
- ()
-{}
-
-
-
-/* Combine the framesheet and mapsheet to create
-   the output sheet */
-/* |-------------------------|
-   |  outputsheet header     |
-   |-------------------------|
-   |  pixel data for frame1  |
-   |-------------------------|
-   |  op data for frame1     |
-   |-------------------------| 
-   |         etc.            | */
-//TODO: processing direction sounds dumb, but cant call it process_framesheet because
-//      its actually the mapsheet and the framesheet. rename to output sheet?
-/* THIS FUNCTION IS NOT DONE */
 long
+#define GENERATE_FILENAME(_N) ((char*) u8_strcat(_N, png_suffix))
 bin_process_facing
 ( ir_setdata framebox,
   apc_facing facing,
   struct bin_pixel_node_t* default_pixel_list
 )
 { struct bin_img_info_t mapsheet_info, framesheet_info;
-  int num_mapchannels, num_framechannels;
+  int num_mapchannels, num_framechannels, x;
+  struct bin_frame_header_t header;
   long facing_start;
   unsigned char* mapdata, * framedata;
+  uint8_t* png_suffix = ".png";
+  struct bin_pixel_node_t* map_pixel_list;
 
   facing_start = ftell(binaryout);
 
   
   /* Set up data pointers to mapsheet and framesheet, as well as their image infos */
-  mapdata = stbi_load(get_framedata_name(get_framebox_facing_mapdata(framebox,SFACE)), &mapsheet_info.width, &mapsheet_info.width, &num_framechannels , 0);
-  framedata = stbi_load(get_framedata_name(get_framebox_facing_framedata(framebox,SFACE)), &framesheet_info.width, &framesheet_info.height, &num_mapchannels, 0);
-  bin_set_img_info(&framesheet_info, get_framebox_facing_framedata(framebox, SFACE));
-  bin_set_img_info(&mapsheet_info, get_framebox_facing_mapdata(framebox, SFACE));
-
-  /* TODO: output framesheet/direction header */
+  mapdata = stbi_load(GENERATE_FILENAME(ir_setdata_name((ir_setdata) ir_framebox_mapsheet(framebox,SFACE))), &mapsheet_info.width, &mapsheet_info.width, &num_framechannels , 0);
+  framedata = stbi_load(GENERATE_FILENAME(ir_setdata_name((ir_setdata) ir_framebox_framesheet(framebox,SFACE))), &framesheet_info.width, &framesheet_info.height, &num_mapchannels, 0);
+  bin_set_img_info(&framesheet_info, ir_framebox_framesheet(framebox, SFACE));
+  bin_set_img_info(&mapsheet_info, ir_framebox_mapsheet(framebox, SFACE));
 
+  /* Allocate space for header */
+  fseek(binaryout, sizeof(header), SEEK_CUR);
+  
+  
+  /* Output framesheet */
+  if(!stbi_write_png(binaryout, framesheet_info.width, framesheet_info.height, 4, mapdata, framesheet_info.fwidth))
+     eprintf("error writing out framesheet\n");
   
-  /* For each frame and map i in framesheet + mapsheet */
-    /* output frame data */
-    /* output op space for frames */
-    /* determine ops in map */
-    /* check if ops are acceptable */
-    /* output ops */
+  /* Output framesheet header */
+  header.width = framesheet_info.fwidth;
+  header.height = framesheet_info.fheight;
+  header.frames = framesheet_info.width / framesheet_info.fwidth; //TODO: division is bad
+  header.op_start = ftell(binaryout);
+  fseek(binaryout, facing_start, SEEK_SET);
+  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);
+      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;
+
+    }
+    /* Determine pixel_list */
+
+    /* Output pixel_list */
   
  
   return facing_start;
   
 }
 
+/* TODO: Please rename all the functions jhc*/
+static inline
+void bin_number_pixel_list
+( struct bin_pixel_node_t* pixel_list )
+{ int num = 0;
+  struct bin_pixel_node_t* iter;
+  while (iter)
+    { iter.data.attach_idx = num++;
+      iter = iter->next;
+    }
+}
+
+/* Assuming at this point that map_pixel_list is valid */
+static inline
+int bin_set_map_pixel_list_attach_idxs
+( struct bin_pixel_node_t* default_pixel_list,
+  struct bin_pixel_node_t* map_pixel_list
+)
+{ struct bin_pixel_node_t* mapiter, defaultiter;
+  mapiter = map_pixel_list;
+  defaultiter = default_pixel_list;
+  while (mapiter && defaultiter)
+    { /* if mapiter.data.ref == defaultiter.data.ref, assign mapiter index_idx to defaultiter */
+      if (mapiter.data.ref == defauliter.data.ref)
+       { defaultiter.data.attach_idx = mapiter.data.attach_idx;
+         mapiter = mapiter->next;
+         defaultiter = defaultiter->next;
+       }
+      else
+       defaultiter = defaultiter->next;
+    }
+}
 
+/* map_pixel_list cannot have more pixels. for all of its pixels,
+   the refs must be represented in default pixel list. 0 if invalid, 1 if valid */
+static inline
+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;
+  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)
+       { 
+       }
+    }
 
 
+  if(!mapiter && defaultiter) //defaultiter is longer so error!
+    return 0;
+
+  
+  
+  
+    
+}
+static inline 
+int bin_process_map_pixel_list
+( struct bin_pixel_node_t* default_pixel_list,
+  struct bin_pixel_node_t* map_pixel_list
+)
+{ /* Determine if pixel_list is valid */
+   
+  /* Determine attach_idx of each pixel, as compared to default pixel list */
+  
+}
 
-/* Insert pixel(s) into the list, z sorted */
 void
+bin_assign_pixel_idxs
+( struct bin_pixel_node_t* pixel_list )
+{ 
+}
+
+/* Insert pixel(s) into the list, z sorted */
+/* number the pixels as you insert them */
+struct bin_pixel_node_t*
 bin_insert_node_into_list
 ( struct bin_pixel_node_t* pixel_list_root,
   struct bin_pixel_node_t* pixel_node
 )
-{ struct bin_pixel_node_t* head_node, *prev_node;
-  int node_z;
+{ struct bin_pixel_node_t* head_node, * prev_node;
 
-  head_node = pixel_list_root->next;
-  node_z = pixel_node->data.z;
 
-  if(head_node == NULL)
-    { head_node = pixel_node;
+  if(pixel_list_root == NULL)
+    { pixel_list_root = pixel_node;
     }
-  prev_node = pixel_list_root;
+  
+  prev_node = head_node = pixel_list_root;  
   while(head_node != NULL)
-    { if(node_z > head_node->data.z)
-       { prev_node = head_node;
-         head_node = head_node->next;
+    { if(pixel_node->data.z > head_node->data.z)
+       { if(head_node->next)
+           { prev_node = head_node;
+             head_node = head_node->next;
+           }
+         else
+           { head_node->next = pixel_node;
+             break;
+           }
        }
-      else if (node_z < head_node->data.z || node_z == head_node->data.z)
+      else if (pixel_node->data.z < head_node->data.z || pixel_node->data.z == head_node->data.z)
        { prev_node->next = pixel_node;
          pixel_node->next = head_node;
          break;
        }
     }
 
+  return pixel_list_root;
+
 
 }
 
@@ -716,7 +846,8 @@ bin_process_pixel
   if(data)
     { /* get ref from 4 bytes of data */
       pixel_node->data.ref = (int) data;
-      /* bitshift by ? to get Z ordering */
+      /* bitshift by ? to get Z */
+      pixel_node->data.z = ((int) data << 24);
 
       /* set x and y */
       pixel_node->data.x = x + init_width ;
@@ -734,35 +865,49 @@ bin_process_pixel
       
 }
 
-/* Returns the non null pixels of a single frame */
+/* Returns the non null pixels of a single map */
 /* TODO: Finish this */
 struct bin_pixel_node_t* 
-bin_map_to_pixel_list
+bin_mapframe_to_pixel_list
 ( struct bin_img_info_t* img_info,
   int init_height,
   int init_width,
   unsigned char* data
 )
-{ int x, y;
+{ int x, y, fheight, fwidth;
   struct bin_pixel_node_t* pixel_list, * pixel_node;
 
   pixel_list = NULL;
 
-  /* Check if frame clips */
+  /* if frame clips, process unclippign frames */
   if( img_info->unaligned_width )
-    ;
+    { if(img_info->height < img_info->fheight)
+       fheight = img_info->height;
+      else
+       fheight = img_info->fheight;
+     }
+  else
+    fheight = img_info->fheight;
   if (img_info->unaligned_height )
-    ;
+    { if(img_info->width < img_info->fwidth)
+       fwidth = img_info->width;
+      else
+       fwidth = img_info->fwidth;
+    }
+  else
+    fwidth = img_info->fwidth;
+    
   
   /* Process the map*/
-  for (y = 0; y < img_info->fheight; y++)
-    { for ( x = 0; x < img_info->fwidth; x++ )
+  for (y = 0; y < fheight; y++)
+    { for ( x = 0; x < fwidth; x++ )
         { pixel_node = bin_process_pixel(data, x, y, init_height, init_width);
-          bin_insert_node_into_list(pixel_list, pixel_node);
+          pixel_list = bin_insert_node_into_list(pixel_list, pixel_node);
+         data += img_info->width - img_info->fwidth; //stride
         }
     }
 
-  return pixel_node;   
+  return pixel_list;   
 }
 
 static inline
@@ -784,7 +929,7 @@ bin_cmp_default_pixel_lists
 ( struct bin_pixel_node_t* pl1,
   struct bin_pixel_node_t* pl2
 )
-{ struct bin_pixel_node_t* pl1p, * pl2p;
+{ struct bin_pixel_node_t* pl1p, * pl2p; 
   int i, pl1_len, pl2_len;
 
   pl1p = pl1;
@@ -818,12 +963,12 @@ bin_find_default_pixel_list
   int num_channels;
   struct bin_img_info_t img_info;
   
-  for (fiter = get_set_frameboxes(set); fiter != NULL; fiter = get_framebox_nextsib(fiter))
+  for (fiter = ir_set_framebox(set); fiter != NULL; fiter = ir_setdata_nextsib(fiter))
     { /* TODO: Stringify the frame name with .png? */
       /* TODO: Add directory changing */
-      data = stbi_load(get_framedata_name(get_framebox_facing_mapdata(fiter, SFACE)), &img_info.width, &img_info.width, &num_channels, 0);
-      bin_set_img_info(&img_info, get_framebox_facing_mapdata(fiter, SFACE));
-      curr_pixel_list = bin_map_to_pixel_list(&img_info, 0, 0, data);
+      data = stbi_load(ir_setdata_name((ir_setdata) ir_framebox_mapsheet(fiter,SFACE) ), &img_info.width, &img_info.width, &num_channels, 0);
+      bin_set_img_info(&img_info, ir_framebox_mapsheet(fiter, SFACE));
+      curr_pixel_list = bin_mapframe_to_pixel_list(&img_info, 0, 0, data);
       default_pixel_list = bin_cmp_default_pixel_lists(curr_pixel_list, default_pixel_list);
 
       free(data);