예제 #1
0
static int destination_each (Babl *babl,
                             void *userdata)
{
  Babl *source      = userdata;
  Babl *destination = babl;

  qux++;
  if (qux % babl_formats_count () == qux / babl_formats_count ())
    printf (" ");
  else
    {
      Babl *temp = babl_fish_path (source, destination);

      if (temp)
        {
          printf ("%s", utf8_bar[babl_list_size (temp->fish_path.conversion_list)]);
          total_length += babl_list_size (temp->fish_path.conversion_list);
          total_cost   += temp->fish_path.cost;
          ok++;
          total++;
        }
      else
        {
          printf (" ");
          total++;
        }
    }
  return 0;
}
예제 #2
0
static void
item_conversions_introspect (Babl *babl)
{
  int i;
  BablList *list;

  list = babl->type.from_list;
  if (list)
    {
      babl_log ("\t\tconversions from %s: %i",
                babl->instance.name, babl_list_size (list));

      for (i = 0; i < babl_list_size (list); i++)
        babl_log ("\t\t\t'%s'", BABL (list->items[i])->instance.name);
   }
}
예제 #3
0
static int
table_destination_each (Babl *babl,
                        void *userdata)
{
  Babl *source      = userdata;
  Babl *destination = babl;

  qux++;
  if (qux % babl_formats_count () == qux / babl_formats_count ())
    fprintf (output_file, "<td class='cell'>&nbsp;</td>");
  else
    {
      const Babl *fish = babl_fish (source, destination);

      babl_assert (fish);


      switch (fish->class_type)
        {
          case BABL_FISH_PATH:

            fprintf (output_file, "<td class='cell'%s><a href='javascript:o()'>%s",
                     fish->fish.pixels / sum_pixels > LIMIT ? " style='background-color: #69f'" : "",
                     utf8_bar[babl_list_size (fish->fish_path.conversion_list)]);

            {
              int i;
              fprintf (output_file, "<div class='tooltip'>");
              fprintf (output_file, "<h3><span class='g'>path</span> %s <span class='g'>to</span> %s</h3>", source->instance.name, destination->instance.name);
              if (fish->fish.processings > 0)
                {
                  fprintf (output_file, "<span class='g'>Processings:</span>%i<br/>", fish->fish.processings);
                  fprintf (output_file, "<span class='g'>Pixels:</span>%li<br/>", fish->fish.pixels);
                }
              fprintf (output_file, "<table>\n");

              fprintf (output_file, "<tr>");
              fprintf (output_file, "<td><em>conversion</em></td>");
              fprintf (output_file, "<td style='text-align:right'><em>cost</em></td>");
              fprintf (output_file, "<td style='text-align:right'><em>error</em></td>");
              fprintf (output_file, "</tr>");

              for (i = 0; i < babl_list_size (fish->fish_path.conversion_list); i++)
                {
                  fprintf (output_file, "<tr>");
                  fprintf (output_file, "<td>%s</td>", BABL (fish->fish_path.conversion_list->items[i])->instance.name);
                  fprintf (output_file, "<td class='r'>%li</td>",
                    babl_conversion_cost (&BABL (fish->fish_path.conversion_list->items[i])->conversion));
                  fprintf (output_file, "<td class='r'>%e</td>",
                    babl_conversion_error (&BABL (fish->fish_path.conversion_list->items[i])->conversion));
                  fprintf (output_file, "</tr>");
                }

              fprintf (output_file, "<tr>");
              fprintf (output_file, "<td><em>total</em></td>");
              fprintf (output_file, "<td class='r'><em>%3.0f</em></td>", fish->fish_path.cost);
              fprintf (output_file, "<td class='r'><em>%e</em></td>", fish->fish.error);
              fprintf (output_file, "</tr>");
              fprintf (output_file, "</table>");
              fprintf (output_file, "</div>");
            }
            fprintf (output_file, "</a></td>\n");
            break;

          case BABL_FISH_REFERENCE:
            fprintf (output_file, "<td class='cell'%s><a href='javascript:o()'>&nbsp",
                     fish->fish.pixels / sum_pixels > LIMIT ? " style='background-color: #f99'" : "");
            fprintf (output_file, "<div class='tooltip'>");
            fprintf (output_file, "<h3><span class='g'>Reference</span> %s <span class='g'>to</span> %s</h3>", source->instance.name, destination->instance.name);

            if (fish->fish.processings > 1)
              {
                fprintf (output_file, "<span class='g'>Processings:</span>%i<br/>", fish->fish.processings);
                fprintf (output_file, "<span class='g'>Pixels:</span>%li<br/>", fish->fish.pixels);
              }
            fprintf (output_file, "</div>");
            fprintf (output_file, "</a></td>\n");
            break;

          case BABL_FISH_SIMPLE:
            fprintf (output_file, "<td class='cell'%s><a href='javascript:o()'>&middot;",
                     fish->fish.pixels / sum_pixels > LIMIT ? " style='background-color: #69f'" : "");
            fprintf (output_file, "<div class='tooltip'>");
            fprintf (output_file, "<h3><span class='g'>Simple</span> %s <span class='g'>to</span> %s</h3>", source->instance.name, destination->instance.name);


            fprintf (output_file, "%s<br/>", BABL (fish->fish_simple.conversion)->instance.name);
            fprintf (output_file, "<span class='g'>cost:</span> %li<br/>", babl_conversion_cost ((fish->fish_simple.conversion)));
            fprintf (output_file, "<span class='g'>error:</span> %e<br/>", babl_conversion_error ((fish->fish_simple.conversion)));

            if (fish->fish.processings > 0)
              {
                fprintf (output_file, "<span class='g'>Processings:</span>%i<br/>", fish->fish.processings);
                fprintf (output_file, "<span class='g'>Pixels:</span>%li<br/>", fish->fish.pixels);
              }
            fprintf (output_file, "</div>");
            fprintf (output_file, "</a></td>\n");
            break;

          default:
            babl_fatal ("Unknown fish type");
            break;
        }
    }
  return 0;
}
예제 #4
0
static long
process_conversion_path (BablList   *path,
                         const void *source_buffer,
                         int         source_bpp,
                         void       *destination_buffer,
                         int         dest_bpp,
                         long        n)
{
  int conversions = babl_list_size (path);

  if (conversions == 1)
    {
      babl_conversion_process (BABL (babl_list_get_first (path)),
                               source_buffer,
                               destination_buffer,
                               n);
    }
  else
    {
      long j;

      void *temp_buffer = align_16 (alloca (MIN(n, MAX_BUFFER_SIZE) * sizeof (double) * 5 + 16));
      void *temp_buffer2 = NULL;

      if (conversions > 2)
        {
          /* We'll need one more auxiliary buffer */
          temp_buffer2 = align_16 (alloca (MIN(n, MAX_BUFFER_SIZE) * sizeof (double) * 5 + 16));
        }




      for (j = 0; j < n; j+= MAX_BUFFER_SIZE)
        {
          long c = MIN (n - j, MAX_BUFFER_SIZE);
          int i;

          /* this is where the loop unrolling should happen */
          void *aux1_buffer = temp_buffer;
          void *aux2_buffer = NULL;
          void *swap_buffer = NULL;
          aux2_buffer = temp_buffer2;

          /* The first conversion goes from source_buffer to aux1_buffer */
          babl_conversion_process (babl_list_get_first (path),
                                   (void*)(((unsigned char*)source_buffer) + (j * source_bpp)),
                                   aux1_buffer,
                                   c);

          /* Process, if any, conversions between the first and the last
           * conversion in the path, in a loop */
          for (i = 1; i < conversions - 1; i++)
            {
              babl_conversion_process (path->items[i],
                                       aux1_buffer,
                                       aux2_buffer,
                                       c);
              /* Swap the auxiliary buffers */
              swap_buffer = aux1_buffer;
              aux1_buffer = aux2_buffer;
              aux2_buffer = swap_buffer;
            }

          /* The last conversion goes from aux1_buffer to destination_buffer */
          babl_conversion_process (babl_list_get_last (path),
                                   aux1_buffer,
                                   (void*)((unsigned char*)destination_buffer + (j * dest_bpp)),
                                   c);
        }
  }

  return n;
}
예제 #5
0
Babl *
babl_fish_path (const Babl *source,
                const Babl *destination)
{
  Babl *babl = NULL;
  char name[BABL_MAX_NAME_LEN];

  create_name (name, source, destination, 1);
  babl = babl_db_exist_by_name (babl_fish_db (), name);
  if (babl)
    {
      /* There is an instance already registered by the required name,
       * returning the preexistent one instead.
       */
      return babl;
    }

  babl = babl_calloc (1, sizeof (BablFishPath) +
                      strlen (name) + 1);
  babl_set_destructor (babl, babl_fish_path_destroy);

  babl->class_type                = BABL_FISH_PATH;
  babl->instance.id               = babl_fish_get_id (source, destination);
  babl->instance.name             = ((char *) babl) + sizeof (BablFishPath);
  strcpy (babl->instance.name, name);
  babl->fish.source               = source;
  babl->fish.destination          = destination;
  babl->fish.processings          = 0;
  babl->fish.pixels               = 0;
  babl->fish.error                = BABL_MAX_COST_VALUE;
  babl->fish_path.cost            = BABL_MAX_COST_VALUE;
  babl->fish_path.loss            = BABL_MAX_COST_VALUE;
  babl->fish_path.conversion_list = babl_list_init_with_size (BABL_HARD_MAX_PATH_LENGTH);

  {
    PathContext pc;
    pc.current_path = babl_list_init_with_size (BABL_HARD_MAX_PATH_LENGTH);
    pc.fish_path = babl;
    pc.to_format = (Babl *) destination;

    if (babl_in_fish_path <= 0)
      babl_mutex_lock (babl_format_mutex);
    /* we hold a global lock whilerunning get_conversion_path since
     * it depends on keeping the various format.visited members in
     * a consistent state, this code path is not performance critical
     * since created fishes are cached.
     */
    babl_in_fish_path++;

    get_conversion_path (&pc, (Babl *) source, 0, max_path_length ());

    babl_in_fish_path--;
    if (babl_in_fish_path <= 0)
      babl_mutex_unlock (babl_format_mutex);
    babl_free (pc.current_path);
  }

  if (babl_list_size (babl->fish_path.conversion_list) == 0)
    {
      babl_free (babl);
      return NULL;
    }

  /* Since there is not an already registered instance by the required
   * name, inserting newly created class into database.
   */
  babl_db_insert (babl_fish_db (), babl);
  return babl;
}
예제 #6
0
static void
get_conversion_path (PathContext *pc,
                     Babl        *current_format,
                     int          current_length,
                     int          max_length)
{
  if (current_length > max_length)
    {
      /* We have reached the maximum recursion
       * depth, let's bail out */
      return;
    }
  else if ((current_length > 0) && (current_format == pc->to_format))
    {
       /* We have found a candidate path, let's
        * see about it's properties */
      double path_cost  = 0.0;
      double ref_cost   = 0.0;
      double path_error = 1.0;
      int    i;

      for (i = 0; i < babl_list_size (pc->current_path); i++)
        {
          path_error *= (1.0 + babl_conversion_error ((BablConversion *) pc->current_path->items[i]));
        }

      if (path_error - 1.0 <= legal_error ()) /* check this before the next;
                                                 which does a more accurate
                                                 measurement of the error */
        {
          FishPathInstrumentation fpi;
          memset (&fpi, 0, sizeof (fpi));

          fpi.source = (Babl*) babl_list_get_first (pc->current_path)->conversion.source;
          fpi.destination = pc->to_format;

          get_path_instrumentation (&fpi, pc->current_path, &path_cost, &ref_cost, &path_error);

          if ((path_cost < ref_cost) && /* do not use paths that took longer to compute than reference */
              (path_cost < pc->fish_path->fish_path.cost) &&
              (path_error <= legal_error ()))
            {
              /* We have found the best path so far,
               * let's copy it into our new fish */
              pc->fish_path->fish_path.cost = path_cost;
              pc->fish_path->fish.error  = path_error;
              babl_list_copy (pc->current_path,
                              pc->fish_path->fish_path.conversion_list);
            }

          destroy_path_instrumentation (&fpi);
        }
    }
  else
    {
      /*
       * Bummer, we have to search deeper... 
       */
      BablList *list;
      int i;


      list = current_format->format.from_list;
      if (list)
        {
          /* Mark the current format in conversion path as visited */
          current_format->format.visited = 1;

          /* Iterate through unvisited formats from the current format ...*/
          for (i = 0; i < babl_list_size (list); i++)
            {
              Babl *next_conversion = BABL (list->items[i]);
              Babl *next_format = BABL (next_conversion->conversion.destination);
              if (!next_format->format.visited)
                {
                  /* next_format is not in the current path, we can pay a visit */
                  babl_list_insert_last (pc->current_path, next_conversion);
                  get_conversion_path (pc, next_format, current_length + 1, max_length);
                  babl_list_remove_last (pc->current_path);
                }
            }

          /* Remove the current format from current path */
          current_format->format.visited = 0;
        }
   }
}