예제 #1
0
void Settingspanel::addSettingcheckbox( const std::string& name, unsigned int posx, unsigned int posy )
{
	std::string str(name);
	std::string strinc(str);
	strinc.append("inc");

	addWidget(str, Vector2i(posx+col1+23+m_margin, posy+row+9), BeWidgetTextPtr(new BeWidgetText(name)));
// 	addWidgetText( str, posx+col1+23, posy+row+9, name );
	addWidgetCheckbox( strinc, Vector2i(posx+col1+m_margin, posy+row), Vector2i(11, 10), "x", Vector2i(3, 8), BeCommand("settings_increase", name), EVENT_NOREPEAT, 0 );
	row += rowspacer;
}
예제 #2
0
// according to cht_format.html from argyll:
// "The keywords and associated data must be used in the following order: BOXES, BOX_SHRINK, REF_ROTATION,
// XLIST, YLIST and EXPECTED."
chart_t *parse_cht(const char *filename)
{
  chart_t *result = (chart_t *)calloc(1, sizeof(chart_t));
  int lineno = 0;

  FILE *fp = fopen(filename, "rb");
  if(!fp)
  {
    fprintf(stderr, "error opening `%s'\n", filename);
    ERROR;
  }

  // parser control
  char line[MAX_LINE_LENGTH] = { 0 };
  parser_state_t last_block = BLOCK_NONE;
  int skip_block = 0;

  // data gathered from the CHT file
  unsigned int n_boxes;
  result->d_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, free);
  result->box_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, free);
  result->patch_sets = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, free_labels_list);

  float x_min = FLT_MAX, x_max = FLT_MIN, y_min = FLT_MAX, y_max = FLT_MIN;

  // main loop over the input file
  while(fgets(line, MAX_LINE_LENGTH, fp))
  {
    if(line[0] == '\0' || line[0] == '\n')
    {
      skip_block = 0;
      continue;
    }
    if(skip_block) continue;

    // we should be at the start of a block now
    char *c = line;
    ssize_t len = strlen(line);
    char *keyword = parse_string(&c);

    if(!g_strcmp0(keyword, "BOXES") && last_block < BLOCK_BOXES)
    {
      last_block = BLOCK_BOXES;
      if(c - line >= len) ERROR;
      n_boxes = parse_double(&c);

      // let's have another loop reading from the file.
      while(fgets(line, MAX_LINE_LENGTH, fp))
      {
        if(line[0] == '\0' || line[0] == '\n') break;

        char *c = line;
        ssize_t len = strlen(line);
        while(*c == ' ') c++;
        if(*c == 'F')
        {
          float x0, y0, x1, y1, x2, y2, x3, y3;
          // using sscanf would be nice, but parsign floats does only work with LANG=C
          // if(sscanf(line, " F _ _ %f %f %f %f %f %f %f %f", &x0, &y0, &x1, &y1, &x2, &y2, &x3, &y3) != 8)
          // ERROR;
          c++;
          while(*c == ' ') c++;
          if(*c++ != '_') ERROR;
          while(*c == ' ') c++;
          if(*c++ != '_') ERROR;
          while(*c == ' ') c++;
          if(c - line >= len) ERROR;
          x0 = parse_double(&c);
          if(c - line >= len) ERROR;
          y0 = parse_double(&c);
          if(c - line >= len) ERROR;
          x1 = parse_double(&c);
          if(c - line >= len) ERROR;
          y1 = parse_double(&c);
          if(c - line >= len) ERROR;
          x2 = parse_double(&c);
          if(c - line >= len) ERROR;
          y2 = parse_double(&c);
          if(c - line >= len) ERROR;
          x3 = parse_double(&c);
          if(c - line >= len) ERROR;
          y3 = parse_double(&c);

          x_min = MIN(x_min, x0);
          x_min = MIN(x_min, x1);
          x_min = MIN(x_min, x2);
          x_min = MIN(x_min, x3);

          y_min = MIN(y_min, y0);
          y_min = MIN(y_min, y1);
          y_min = MIN(y_min, y2);
          y_min = MIN(y_min, y3);

          x_max = MAX(x_max, x0);
          x_max = MAX(x_max, x1);
          x_max = MAX(x_max, x2);
          x_max = MAX(x_max, x3);

          y_max = MAX(y_max, y0);
          y_max = MAX(y_max, y1);
          y_max = MAX(y_max, y2);
          y_max = MAX(y_max, y3);

          f_line_t *l = (f_line_t *)malloc(sizeof(f_line_t));

          l->p[0].x = x0;
          l->p[0].y = y0;
          l->p[1].x = x1;
          l->p[1].y = y1;
          l->p[2].x = x2;
          l->p[2].y = y2;
          l->p[3].x = x3;
          l->p[3].y = y3;

          result->f_list = g_list_append(result->f_list, l);
        }
        // these get parsed the same way
        else if((*c == 'D') || (*c == 'X') || (*c == 'Y'))
        {
          char kl, *lxs, *lxe, *lys, *lye;
          float w, h, xo, yo, xi, yi;
          kl = *c;
          *c++ = '\0';

          if(c - line >= len) ERROR;
          lxs = parse_string(&c);
          if(c - line >= len) ERROR;
          lxe = parse_string(&c);
          if(c - line >= len) ERROR;
          lys = parse_string(&c);
          if(c - line >= len) ERROR;
          lye = parse_string(&c);

          if(c - line >= len) ERROR;
          w = parse_double(&c);
          if(c - line >= len) ERROR;
          h = parse_double(&c);
          if(c - line >= len) ERROR;
          xo = parse_double(&c);
          if(c - line >= len) ERROR;
          yo = parse_double(&c);
          if(c - line >= len) ERROR;
          xi = parse_double(&c);
          if(c - line >= len) ERROR;
          yi = parse_double(&c);

          x_min = MIN(x_min, xo);
          y_min = MIN(y_min, yo);

          int x_steps = 1, y_steps = 1;
          size_t lxs_len = strlen(lxs), lxe_len = strlen(lxe), lys_len = strlen(lys), lye_len = strlen(lye);
          if(lxs_len > lxe_len || lys_len > lye_len) ERROR;

          char x_label[lxe_len + 1],
              y_label[lye_len + 1]; // make sure there is enough room to add another char in the beginning

          char *first_label = NULL, *last_label = NULL;
          GList *labels = NULL;

          float y = yo;
          memcpy(y_label, lys, lys_len + 1);
          while(1)
          {
            float x = xo;
            memcpy(x_label, lxs, lxs_len + 1);
            while(1)
            {
              // build the label of the box
              char *label;
              if(!g_strcmp0(x_label, "_"))
                label = g_strdup(y_label);
              else if(!g_strcmp0(y_label, "_"))
                label = g_strdup(x_label);
              else
              {
                if(kl == 'Y')
                  label = g_strconcat(y_label, x_label, NULL);
                else
                  label = g_strconcat(x_label, y_label, NULL);
              }

              if(!first_label) first_label = label;
              last_label = label;

              // store it
              box_t *box = (box_t *)calloc(1, sizeof(box_t));
              box->p.x = x;
              box->p.y = y;
              box->w = w;
              box->h = h;
              box->color_space = DT_COLORSPACE_NONE; // no color for this box yet
              if(kl == 'D')
                g_hash_table_insert(result->d_table, label, box);
              else
                g_hash_table_insert(result->box_table, label, box);
              if(kl == 'X' || kl == 'Y') labels = g_list_append(labels, g_strdup(label));

              // increment in x direction
              if(!g_strcmp0(x_label, lxe)) break;
              x += xi;
              x_steps++;
              if(!strinc(x_label, sizeof(x_label))) ERROR;
            }
            x_max = MAX(x_max, x + w);
            // increment in y direction
            if(!g_strcmp0(y_label, lye)) break;
            y += yi;
            y_steps++;
            if(!strinc(y_label, sizeof(y_label))) ERROR;
          }
          y_max = MAX(y_max, y + h);
          if(kl == 'X' || kl == 'Y')
            g_hash_table_insert(result->patch_sets, g_strdup_printf("%s .. %s", first_label, last_label), labels);
        }
        else
          ERROR;
      }

      if(n_boxes != g_hash_table_size(result->d_table) + g_hash_table_size(result->box_table)) ERROR;

      // all the box lines are read and we know the bounding box,
      // so let's scale all the values to have a bounding box with the longer side having length 1 and start
      // at (0, 0)

      result->bb_w = x_max - x_min;
      result->bb_h = y_max - y_min;

#define SCALE_X(x) x = (x - x_min) / result->bb_w
#define SCALE_Y(y) y = (y - y_min) / result->bb_h

      GList *iter = result->f_list;
      while(iter)
      {
        f_line_t *f = iter->data;
        for(int i = 0; i < 4; i++)
        {
          SCALE_X(f->p[i].x);
          SCALE_Y(f->p[i].y);
        }
        iter = g_list_next(iter);
      }

      GHashTableIter table_iter;
      gpointer key, value;

      g_hash_table_iter_init(&table_iter, result->d_table);
      while(g_hash_table_iter_next(&table_iter, &key, &value))
      {
        box_t *box = (box_t *)value;
        SCALE_X(box->p.x);
        SCALE_Y(box->p.y);
        box->w /= result->bb_w;
        box->h /= result->bb_h;
      }

      g_hash_table_iter_init(&table_iter, result->box_table);
      while(g_hash_table_iter_next(&table_iter, &key, &value))
      {
        box_t *box = (box_t *)value;
        SCALE_X(box->p.x);
        SCALE_Y(box->p.y);
        box->w /= result->bb_w;
        box->h /= result->bb_h;
      }

#undef SCALE_X
#undef SCALE_Y
    }
    else if(!g_strcmp0(keyword, "BOX_SHRINK") && last_block < BLOCK_BOX_SHRINK)
    {
      last_block = BLOCK_BOX_SHRINK;
      if(c - line >= len) ERROR;
      result->box_shrink = parse_double(&c);
    }
    else if(!g_strcmp0(keyword, "REF_ROTATION") && last_block < BLOCK_REF_ROTATION)
    {
      last_block = BLOCK_REF_ROTATION;
      if(c - line >= len) ERROR;
      result->ref_rotation = parse_double(&c);
    }
    else if(!g_strcmp0(keyword, "XLIST") && last_block < BLOCK_XLIST)
    {
      last_block = BLOCK_XLIST;
      // skip until empty line, we don't care about these
      skip_block = 1;
    }
    else if(!g_strcmp0(keyword, "YLIST") && last_block < BLOCK_YLIST)
    {
      last_block = BLOCK_YLIST;
      // skip until empty line, we don't care about these
      skip_block = 1;
    }
    else if(!g_strcmp0(keyword, "EXPECTED") && last_block < BLOCK_EXPECTED)
    {
      last_block = BLOCK_EXPECTED;
      dt_colorspaces_color_profile_type_t color_space = DT_COLORSPACE_NONE;
      if(c - line >= len) ERROR;
      char *cs = parse_string(&c);
      if(c - line >= len) ERROR;
      unsigned int n_colors = parse_double(&c);

      if(!g_strcmp0(cs, "XYZ"))
        color_space = DT_COLORSPACE_XYZ;
      else if(!g_strcmp0(cs, "LAB"))
        color_space = DT_COLORSPACE_LAB;
      else
        ERROR;

      // read and store the numbers.
      // we use them 1) to draw visual hints on the grid and 2) as a fallback reference set

      // let's have another loop reading from the file.
      while(fgets(line, MAX_LINE_LENGTH, fp))
      {
        if(line[0] == '\0' || line[0] == '\n') break;
        n_colors--;
        ssize_t len = strlen(line);
        char *c = line;

        char *label = parse_string(&c);
        box_t *box = (box_t *)g_hash_table_lookup(result->box_table, label);
        if(!box) ERROR;

        if(c - line >= len) ERROR;
        float c0 = parse_double(&c);
        if(c - line >= len) ERROR;
        float c1 = parse_double(&c);
        if(c - line >= len) ERROR;
        float c2 = parse_double(&c);
        set_color(box, color_space, c0, c1, c2);
      }
      if(n_colors != 0) ERROR;
    }
    else
    {
      fprintf(stderr, "unknown keyword `%s'\n", keyword);
      ERROR;
    }
  }

  fprintf(stderr, "cht `%s' done\n", filename);
  goto end;

error:
  fprintf(stderr, "error parsing CHT file, (%s:%d)\n", __FUNCTION__, lineno);
  // clean up
  free_chart(result);
  result = NULL;

end:
  if(fp) fclose(fp);
  return result;
}