Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
107
Task/Bitmap-Flood-fill/C/bitmap-flood-fill-1.c
Normal file
107
Task/Bitmap-Flood-fill/C/bitmap-flood-fill-1.c
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* RosettaCode: Bitmap/Flood fill, language C, dialects C89, C99, C11.
|
||||
*
|
||||
* This is an implementation of the recursive algorithm. For the sake of
|
||||
* simplicity, instead of reading files as JPEG, PNG, etc., the program
|
||||
* read and write Portable Bit Map (PBM) files in plain text format.
|
||||
* Portable Bit Map files can also be read and written with GNU GIMP.
|
||||
*
|
||||
* The program is just an example, so the image size is limited to 2048x2048,
|
||||
* the image can only be black and white, there is no run-time validation.
|
||||
*
|
||||
* Data is read from a standard input stream, the results are written to the
|
||||
* standard output file.
|
||||
*
|
||||
* In order for this program to work properly it is necessary to allocate
|
||||
* enough memory for the program stack. For example, in Microsoft Visual Studio,
|
||||
* the option /stack:134217728 declares a 128MB stack instead of the default
|
||||
* size of 1MB.
|
||||
*/
|
||||
#define _CRT_SECURE_NO_WARNINGS /* Unlock printf etc. in MSVC */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define MAXSIZE 2048
|
||||
#define BYTE unsigned char
|
||||
|
||||
static int width, height;
|
||||
static BYTE bitmap[MAXSIZE][MAXSIZE];
|
||||
static BYTE oldColor;
|
||||
static BYTE newColor;
|
||||
|
||||
void floodFill(int i, int j)
|
||||
{
|
||||
if ( 0 <= i && i < height
|
||||
&& 0 <= j && j < width
|
||||
&& bitmap[i][j] == oldColor )
|
||||
{
|
||||
bitmap[i][j] = newColor;
|
||||
floodFill(i-1,j);
|
||||
floodFill(i+1,j);
|
||||
floodFill(i,j-1);
|
||||
floodFill(i,j+1);
|
||||
}
|
||||
}
|
||||
|
||||
/* *****************************************************************************
|
||||
* Input/output routines.
|
||||
*/
|
||||
|
||||
void skipLine(FILE* file)
|
||||
{
|
||||
while(!ferror(file) && !feof(file) && fgetc(file) != '\n')
|
||||
;
|
||||
}
|
||||
|
||||
void skipCommentLines(FILE* file)
|
||||
{
|
||||
int c;
|
||||
int comment = '#';
|
||||
|
||||
while ((c = fgetc(file)) == comment)
|
||||
skipLine(file);
|
||||
ungetc(c,file);
|
||||
}
|
||||
|
||||
readPortableBitMap(FILE* file)
|
||||
{
|
||||
int i,j;
|
||||
|
||||
skipLine(file);
|
||||
skipCommentLines(file); fscanf(file,"%d",&width);
|
||||
skipCommentLines(file); fscanf(file,"%d",&height);
|
||||
skipCommentLines(file);
|
||||
|
||||
if ( width <= MAXSIZE && height <= MAXSIZE )
|
||||
for ( i = 0; i < height; i++ )
|
||||
for ( j = 0; j < width; j++ )
|
||||
fscanf(file,"%1d",&(bitmap[i][j]));
|
||||
else exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
void writePortableBitMap(FILE* file)
|
||||
{
|
||||
int i,j;
|
||||
fprintf(file,"P1\n");
|
||||
fprintf(file,"%d %d\n", width, height);
|
||||
for ( i = 0; i < height; i++ )
|
||||
{
|
||||
for ( j = 0; j < width; j++ )
|
||||
fprintf(file,"%1d", bitmap[i][j]);
|
||||
fprintf(file,"\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* *****************************************************************************
|
||||
* The main entry point.
|
||||
*/
|
||||
|
||||
int main(void)
|
||||
{
|
||||
oldColor = 1;
|
||||
newColor = oldColor ? 0 : 1;
|
||||
readPortableBitMap(stdin);
|
||||
floodFill(height/2,width/2);
|
||||
writePortableBitMap(stdout);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
106
Task/Bitmap-Flood-fill/C/bitmap-flood-fill-2.c
Normal file
106
Task/Bitmap-Flood-fill/C/bitmap-flood-fill-2.c
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
// http://commons.wikimedia.org/wiki/File:Julia_immediate_basin_1_3.png
|
||||
|
||||
unsigned int f(unsigned int _iX, unsigned int _iY)
|
||||
/*
|
||||
gives position of point (iX,iY) in 1D array ; uses also global variables
|
||||
it does not check if index is good so memory error is possible
|
||||
*/
|
||||
{return (_iX + (iYmax-_iY-1)*iXmax );}
|
||||
|
||||
|
||||
int FillContour(int iXseed, int iYseed, unsigned char color, unsigned char _data[])
|
||||
{
|
||||
/*
|
||||
fills contour with black border ( color = iJulia) using seed point inside contour
|
||||
and horizontal lines
|
||||
it starts from seed point, saves max right( iXmaxLocal) and max left ( iXminLocal) interior points of horizontal line,
|
||||
in new line ( iY+1 or iY-1) it computes new interior point : iXmidLocal=iXminLocal + (iXmaxLocal-iXminLocal)/2;
|
||||
result is stored in _data array : 1D array of 1-bit colors ( shades of gray)
|
||||
it does not check if index of _data array is good so memory error is possible
|
||||
*/
|
||||
|
||||
|
||||
int iX, /* seed integer coordinate */
|
||||
iY=iYseed,
|
||||
/* most interior point of line iY */
|
||||
iXmidLocal=iXseed,
|
||||
/* min and max of interior points of horizontal line iY */
|
||||
iXminLocal,
|
||||
iXmaxLocal;
|
||||
int i ; /* index of _data array */;
|
||||
|
||||
|
||||
/* --------- move up --------------- */
|
||||
do{
|
||||
iX=iXmidLocal;
|
||||
i =f(iX,iY); /* index of _data array */;
|
||||
|
||||
/* move to right */
|
||||
while (_data[i]==iInterior)
|
||||
{ _data[i]=color;
|
||||
iX+=1;
|
||||
i=f(iX,iY);
|
||||
}
|
||||
iXmaxLocal=iX-1;
|
||||
|
||||
/* move to left */
|
||||
iX=iXmidLocal-1;
|
||||
i=f(iX,iY);
|
||||
while (_data[i]==iInterior)
|
||||
{ _data[i]=color;
|
||||
iX-=1;
|
||||
i=f(iX,iY);
|
||||
}
|
||||
iXminLocal=iX+1;
|
||||
|
||||
|
||||
iY+=1; /* move up */
|
||||
iXmidLocal=iXminLocal + (iXmaxLocal-iXminLocal)/2; /* new iX inside contour */
|
||||
i=f(iXmidLocal,iY); /* index of _data array */;
|
||||
if ( _data[i]==iJulia) break; /* it should not cross the border */
|
||||
|
||||
} while (iY<iYmax);
|
||||
|
||||
|
||||
/* ------ move down ----------------- */
|
||||
iXmidLocal=iXseed;
|
||||
iY=iYseed-1;
|
||||
|
||||
|
||||
do{
|
||||
iX=iXmidLocal;
|
||||
i =f(iX,iY); /* index of _data array */;
|
||||
|
||||
/* move to right */
|
||||
while (_data[i]==iInterior) /* */
|
||||
{ _data[i]=color;
|
||||
iX+=1;
|
||||
i=f(iX,iY);
|
||||
}
|
||||
iXmaxLocal=iX-1;
|
||||
|
||||
/* move to left */
|
||||
iX=iXmidLocal-1;
|
||||
i=f(iX,iY);
|
||||
while (_data[i]==iInterior) /* */
|
||||
{ _data[i]=color;
|
||||
iX-=1; /* move to right */
|
||||
i=f(iX,iY);
|
||||
}
|
||||
iXminLocal=iX+1;
|
||||
|
||||
iY-=1; /* move down */
|
||||
iXmidLocal=iXminLocal + (iXmaxLocal-iXminLocal)/2; /* new iX inside contour */
|
||||
i=f(iXmidLocal,iY); /* index of _data array */;
|
||||
if ( _data[i]==iJulia) break; /* it should not cross the border */
|
||||
} while (0<iY);
|
||||
|
||||
/* mark seed point by big pixel */
|
||||
const int iSide =iXmax/500; /* half of width or height of big pixel */
|
||||
for(iY=iYseed-iSide;iY<=iYseed+iSide;++iY){
|
||||
for(iX=iXseed-iSide;iX<=iXseed+iSide;++iX){
|
||||
i= f(iX,iY); /* index of _data array */
|
||||
_data[i]=10;}}
|
||||
|
||||
return 0;
|
||||
}
|
||||
9
Task/Bitmap-Flood-fill/C/bitmap-flood-fill-3.c
Normal file
9
Task/Bitmap-Flood-fill/C/bitmap-flood-fill-3.c
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
/* #include <sys/queue.h> */
|
||||
typedef struct {
|
||||
color_component red, green, blue;
|
||||
} rgb_color;
|
||||
typedef rgb_color *rgb_color_p;
|
||||
|
||||
void floodfill(image img, int px, int py,
|
||||
rgb_color_p bankscolor,
|
||||
rgb_color_p rcolor);
|
||||
93
Task/Bitmap-Flood-fill/C/bitmap-flood-fill-4.c
Normal file
93
Task/Bitmap-Flood-fill/C/bitmap-flood-fill-4.c
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
#include "imglib.h"
|
||||
|
||||
typedef struct _ffill_node {
|
||||
int px, py;
|
||||
TAILQ_ENTRY(_ffill_node) nodes;
|
||||
} _ffill_node_t;
|
||||
TAILQ_HEAD(_ffill_queue_s, _ffill_node);
|
||||
typedef struct _ffill_queue_s _ffill_queue;
|
||||
|
||||
inline void _ffill_removehead(_ffill_queue *q)
|
||||
{
|
||||
_ffill_node_t *n = q->tqh_first;
|
||||
if ( n != NULL ) {
|
||||
TAILQ_REMOVE(q, n, nodes);
|
||||
free(n);
|
||||
}
|
||||
}
|
||||
|
||||
inline void _ffill_enqueue(_ffill_queue *q, int px, int py)
|
||||
{
|
||||
_ffill_node_t *node;
|
||||
node = malloc(sizeof(_ffill_node_t));
|
||||
if ( node != NULL ) {
|
||||
node->px = px; node->py = py;
|
||||
TAILQ_INSERT_TAIL(q, node, nodes);
|
||||
}
|
||||
}
|
||||
|
||||
inline double color_distance( rgb_color_p a, rgb_color_p b )
|
||||
{
|
||||
return sqrt( (double)(a->red - b->red)*(a->red - b->red) +
|
||||
(double)(a->green - b->green)*(a->green - b->green) +
|
||||
(double)(a->blue - b->blue)*(a->blue - b->blue) ) / (256.0*sqrt(3.0));
|
||||
}
|
||||
|
||||
inline void _ffill_rgbcolor(image img, rgb_color_p tc, int px, int py)
|
||||
{
|
||||
tc->red = GET_PIXEL(img, px, py)[0];
|
||||
tc->green = GET_PIXEL(img, px, py)[1];
|
||||
tc->blue = GET_PIXEL(img, px, py)[2];
|
||||
}
|
||||
|
||||
|
||||
#define NSOE(X,Y) do { \
|
||||
if ( ((X)>=0)&&((Y)>=0) && ((X)<img->width)&&((Y)<img->height)) { \
|
||||
_ffill_rgbcolor(img, &thisnode, (X), (Y)); \
|
||||
if ( color_distance(&thisnode, bankscolor) > tolerance ) { \
|
||||
if (color_distance(&thisnode, rcolor) > 0.0) { \
|
||||
put_pixel_unsafe(img, (X), (Y), rcolor->red, \
|
||||
rcolor->green, \
|
||||
rcolor->blue); \
|
||||
_ffill_enqueue(&head, (X), (Y)); \
|
||||
pixelcount++; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
|
||||
unsigned int floodfill(image img, int px, int py,
|
||||
rgb_color_p bankscolor,
|
||||
rgb_color_p rcolor)
|
||||
{
|
||||
_ffill_queue head;
|
||||
rgb_color thisnode;
|
||||
unsigned int pixelcount = 0;
|
||||
double tolerance = 0.05;
|
||||
|
||||
if ( (px < 0) || (py < 0) || (px >= img->width) || (py >= img->height) )
|
||||
return;
|
||||
|
||||
TAILQ_INIT(&head);
|
||||
|
||||
_ffill_rgbcolor(img, &thisnode, px, py);
|
||||
if ( color_distance(&thisnode, bankscolor) <= tolerance ) return;
|
||||
|
||||
_ffill_enqueue(&head, px, py);
|
||||
while( head.tqh_first != NULL ) {
|
||||
_ffill_node_t *n = head.tqh_first;
|
||||
_ffill_rgbcolor(img, &thisnode, n->px, n->py);
|
||||
if ( color_distance(&thisnode, bankscolor) > tolerance ) {
|
||||
put_pixel_unsafe(img, n->px, n->py, rcolor->red, rcolor->green, rcolor->blue);
|
||||
pixelcount++;
|
||||
}
|
||||
int tx = n->px, ty = n->py;
|
||||
_ffill_removehead(&head);
|
||||
NSOE(tx - 1, ty);
|
||||
NSOE(tx + 1, ty);
|
||||
NSOE(tx, ty - 1);
|
||||
NSOE(tx, ty + 1);
|
||||
}
|
||||
return pixelcount;
|
||||
}
|
||||
27
Task/Bitmap-Flood-fill/C/bitmap-flood-fill-5.c
Normal file
27
Task/Bitmap-Flood-fill/C/bitmap-flood-fill-5.c
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "imglib.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
image animage;
|
||||
rgb_color ic;
|
||||
rgb_color rc;
|
||||
|
||||
if ( argc > 1 ) {
|
||||
animage = read_image(argv[1]);
|
||||
if ( animage != NULL ) {
|
||||
ic.red = 255; /* = 0; */
|
||||
ic.green = 255; /* = 0; */
|
||||
ic.blue = 255; /* = 0; */
|
||||
rc.red = 0;
|
||||
rc.green = 255;
|
||||
rc.blue = 0;
|
||||
floodfill(animage, 100, 100, &ic, &rc);
|
||||
/* 150, 150 */
|
||||
print_jpg(animage, 90);
|
||||
free(animage);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue