/* * blackwhite 1.00 -- image filter plug-in for The GIMP * Copyright (C) 1996 Marc Bless * * E-mail: bless@ai-lab.fh-furtwangen.de * WWW: www.ai-lab.fh-furtwangen.de/~bless * * 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, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include "gimp.h" static void scale_callback (int, void *, void *); static void toggle_callback (int, void *, void *); static void ok_callback (int, void *, void *); static void cancel_callback (int, void *, void *); static void blackwhite (Image, Image); static void saveimage (void); static void freshen (void); static int aapply; static int aapplyID; static int dialogID; static int allpix; static int allpixID; static char *prog_name; static unsigned char *saved; Image input, output; /* amount of % */ long amount = 0; int main (argc, argv) int argc; char **argv; { int scaleID; int mainID; int textID; prog_name = argv[0]; if (gimp_init (argc, argv)) { input = 0; output = 0; input = gimp_get_input_image (0); output = gimp_get_output_image (0); if (input && output) switch (gimp_image_type (input)) { case RGB_IMAGE: case GRAY_IMAGE: saveimage (); dialogID = gimp_new_dialog ("Black/White"); mainID = gimp_new_row_group (dialogID, DEFAULT, NORMAL, ""); textID = gimp_new_label (dialogID, mainID, "Color values below the amount become 0, above become 255."); scaleID = gimp_new_scale (dialogID, mainID, 0, 255, amount, 0); if (gimp_image_type (input) == RGB_IMAGE) { allpixID = gimp_new_check_button (dialogID, mainID, "Process on each RGB value instead of whole triplet"); allpix = 0; gimp_change_item (dialogID, allpixID, sizeof (allpix), &allpix); gimp_add_callback (dialogID, allpixID, toggle_callback, &allpix); } aapplyID = gimp_new_check_button (dialogID, mainID, "Auto Apply"); aapply = 1; gimp_change_item (dialogID, aapplyID, sizeof (aapply), &aapply); gimp_add_callback (dialogID, aapplyID, toggle_callback, &aapply); gimp_add_callback (dialogID, scaleID, scale_callback, &amount); gimp_add_callback (dialogID, gimp_ok_item_id (dialogID), ok_callback, 0); gimp_add_callback (dialogID, gimp_cancel_item_id (dialogID), cancel_callback, 0); blackwhite (input, output); gimp_update_image (output); if (!gimp_show_dialog (dialogID)) { freshen (); } else { gimp_set_params (sizeof (amount), &amount); blackwhite (input, output); } gimp_update_image (output); free (saved); break; case INDEXED_IMAGE: gimp_message ("drf: cannot operate on indexed color images"); break; default: gimp_message ("drf: cannot operate on unknown image types"); break; } if (input) gimp_free_image (input); if (output) gimp_free_image (output); gimp_quit (); } return 0; } static void toggle_callback (int itemID, void *client_data, void *call_data) { *((long*) client_data) = *((long*) call_data); if (aapply) { blackwhite (input, output); gimp_update_image (output); } else { freshen (); gimp_update_image (output); } } static void saveimage (void) { saved = (unsigned char *) malloc (gimp_image_width (input) * gimp_image_height (input) * gimp_image_channels (input)); memcpy (saved, gimp_image_data (input), gimp_image_width (input) * gimp_image_height (input) * gimp_image_channels (input)); } static void freshen (void) { memcpy (gimp_image_data (output), saved, gimp_image_width (input) * gimp_image_height (input) * gimp_image_channels (input)); } static void scale_callback (item_ID, client_data, call_data) int item_ID; void *client_data; void *call_data; { if (aapply && (*((long*) client_data) != *((long*) call_data))) { *((long*) client_data) = *((long*) call_data); blackwhite (input, output); gimp_update_image (output); } *((long*) client_data) = *((long*) call_data); } static void ok_callback (item_ID, client_data, call_data) int item_ID; void *client_data; void *call_data; { gimp_close_dialog (dialogID, 1); } static void cancel_callback (item_ID, client_data, call_data) int item_ID; void *client_data; void *call_data; { gimp_close_dialog (dialogID, 0); } static void blackwhite (input, output) Image input, output; { long width, height; long channels, rowstride; unsigned char *src_row, *dest_row; unsigned char *src, *dest; short row, col; int x1, y1, x2, y2; int i; int avg; gimp_image_area (input, &x1, &y1, &x2, &y2); width = gimp_image_width (input); height = gimp_image_height (input); channels = gimp_image_channels (input); rowstride = width * channels; src_row = saved; dest_row = gimp_image_data (output); /* x1 *= channels; x2 *= channels; */ src_row += rowstride * y1 + x1 * channels; dest_row += rowstride * y1 + x1 * channels; for (row = y1; row < y2; row++) { src = src_row; dest = dest_row; for (col = x1; col < x2; col++) if (allpix) { for (i = 0; i < channels; i++) *dest++ = (*src++ >= amount) ? 255 : 0; } else { avg = 0; for (i = 0; i < channels; i++) avg += *src++; avg /= 3; for (i = 0; i < channels; i++) *dest++ = (avg >= amount) ? 255 : 0; } src_row += rowstride; dest_row += rowstride; } }