/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* Pix
*
* Copyright (C) 2009-2014 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#include
#include
#include "gth-file-tool-negative.h"
static gpointer
negative_exec (GthAsyncTask *task,
gpointer user_data)
{
cairo_surface_t *source;
cairo_format_t format;
int width;
int height;
int source_stride;
cairo_surface_t *destination;
int destination_stride;
unsigned char *p_source_line;
unsigned char *p_destination_line;
unsigned char *p_source;
unsigned char *p_destination;
gboolean cancelled;
double progress;
int x, y, temp;
unsigned char red, green, blue, alpha;
source = gth_image_task_get_source_surface (GTH_IMAGE_TASK (task));
format = cairo_image_surface_get_format (source);
width = cairo_image_surface_get_width (source);
height = cairo_image_surface_get_height (source);
source_stride = cairo_image_surface_get_stride (source);
destination = cairo_image_surface_create (format, width, height);
destination_stride = cairo_image_surface_get_stride (destination);
p_source_line = _cairo_image_surface_flush_and_get_data (source);
p_destination_line = _cairo_image_surface_flush_and_get_data (destination);
for (y = 0; y < height; y++) {
gth_async_task_get_data (task, NULL, &cancelled, NULL);
if (cancelled) {
cairo_surface_destroy (destination);
cairo_surface_destroy (source);
return NULL;
}
progress = (double) y / height;
gth_async_task_set_data (task, NULL, NULL, &progress);
p_source = p_source_line;
p_destination = p_destination_line;
for (x = 0; x < width; x++) {
CAIRO_GET_RGBA (p_source, red, green, blue, alpha);
CAIRO_SET_RGBA (p_destination,
255 - red,
255 - green,
255 - blue,
alpha);
p_source += 4;
p_destination += 4;
}
p_source_line += source_stride;
p_destination_line += destination_stride;
}
cairo_surface_mark_dirty (destination);
gth_image_task_set_destination_surface (GTH_IMAGE_TASK (task), destination);
cairo_surface_destroy (destination);
cairo_surface_destroy (source);
return NULL;
}
void
negative_add_to_special_effects (GthFilterGrid *grid)
{
gth_filter_grid_add_filter (grid,
GTH_FILTER_GRID_NEW_FILTER_ID,
gth_image_task_new (_("Applying changes"), NULL, negative_exec, NULL, NULL, NULL),
_("Negative"),
NULL);
}