xcf_load_channel (XcfInfo   *info,
                  GimpImage *image)
{
  GimpChannel *channel;
  goffset      hierarchy_offset;
  gint         width;
  gint         height;
  gboolean     is_fs_drawable;
  gchar       *name;
  GimpRGB      color = { 0.0, 0.0, 0.0, GIMP_OPACITY_OPAQUE };

  /* check and see if this is the drawable the floating selection
   *  is attached to. if it is then we'll do the attachment in our caller.
   */
  is_fs_drawable = (info->cp == info->floating_sel_offset);

  /* read in the layer width, height and name */
  xcf_read_int32 (info, (guint32 *) &width,  1);
  xcf_read_int32 (info, (guint32 *) &height, 1);
  if (width <= 0 || height <= 0)
    return NULL;

  xcf_read_string (info, &name, 1);

  /* create a new channel */
  channel = gimp_channel_new (image, width, height, name, &color);
  g_free (name);
  if (!channel)
    return NULL;

  /* read in the channel properties */
  if (! xcf_load_channel_props (info, image, &channel))
    goto error;

  xcf_progress_update (info);

  /* read the hierarchy and layer mask offsets */
  xcf_read_offset (info, &hierarchy_offset, 1);

  /* read in the hierarchy */
  if (! xcf_seek_pos (info, hierarchy_offset, NULL))
    goto error;

  if (! xcf_load_buffer (info,
                         gimp_drawable_get_buffer (GIMP_DRAWABLE (channel))))
    goto error;

  xcf_progress_update (info);

  if (is_fs_drawable)
    info->floating_sel_drawable = GIMP_DRAWABLE (channel);

  return channel;

 error:
  /* don't unref the selection of a partially loaded XCF */
  if (channel != gimp_image_get_mask (image))
    {
      GList *iter;

      for (iter = info->selected_channels; iter; iter = iter->next)
        if (channel == iter->data)
          {
            info->selected_channels = g_list_delete_link (info->selected_channels, iter);
            break;
          }

      if (info->floating_sel_drawable == GIMP_DRAWABLE (channel))
        info->floating_sel_drawable = NULL;

      g_object_unref (channel);
    }

  return NULL;
}
xcf_load_channel (XcfInfo   *info,
                  GimpImage *image)
{
  GimpChannel *channel;
  goffset      hierarchy_offset;
  gint         width;
  gint         height;
  gboolean     is_fs_drawable;
  gchar       *name;
  GimpRGB      color = { 0.0, 0.0, 0.0, GIMP_OPACITY_OPAQUE };

   
  is_fs_drawable = (info->cp == info->floating_sel_offset);

   
  xcf_read_int32 (info, (guint32 *) &width,  1);
  xcf_read_int32 (info, (guint32 *) &height, 1);
  if (width <= 0 || height <= 0)
    return NULL;

  xcf_read_string (info, &name, 1);

   
  channel = gimp_channel_new (image, width, height, name, &color);
  g_free (name);
  if (!channel)
    return NULL;

   
  if (! xcf_load_channel_props (info, image, &channel))
    goto error;

  xcf_progress_update (info);

   
  xcf_read_offset (info, &hierarchy_offset, 1);

   
  if (! xcf_seek_pos (info, hierarchy_offset, NULL))
    goto error;

  if (! xcf_load_buffer (info,
                         gimp_drawable_get_buffer (GIMP_DRAWABLE (channel))))
    goto error;

  xcf_progress_update (info);

  if (is_fs_drawable)
    info->floating_sel_drawable = GIMP_DRAWABLE (channel);

  return channel;

 error:
   
  if (channel != gimp_image_get_mask (image))
    {
      GList *iter;

      for (iter = info->selected_channels; iter; iter = iter->next)
        if (channel == iter->data)
          {
            info->selected_channels = g_list_delete_link (info->selected_channels, iter);
            break;
          }

      if (info->floating_sel_drawable == GIMP_DRAWABLE (channel))
        info->floating_sel_drawable = NULL;

      g_object_unref (channel);
    }

  return NULL;
}