সি - সরল রেখা
সি তে একটি প্রাথমিক পদ্ধতির যা পিপিএম ফাইলগুলিতে কাজ করে। অ্যালগরিদম সমস্ত পিক্সেল পূরণ করার জন্য অনুকূল লাইন দৈর্ঘ্যের সাথে উল্লম্ব রেখা স্থাপন করার চেষ্টা করে। ব্যাকগ্রাউন্ড রঙ এবং লাইন রংগুলি মূল চিত্রের (প্রতিটি রঙের চ্যানেলের মধ্যম) গড় মূল্য হিসাবে গণনা করা হয়:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#define SIGN(x) ((x > 0) ? 1 : (x < 0) ? -1 : 0)
#define MIN(x, y) ((x > y) ? y : x)
#define MAX(x, y) ((x > y) ? x : y)
typedef struct {
size_t width;
size_t height;
unsigned char *r;
unsigned char *g;
unsigned char *b;
} image;
typedef struct {
unsigned char r;
unsigned char g;
unsigned char b;
} color;
void init_image(image *data, size_t width, size_t height) {
data->width = width;
data->height = height;
data->r = malloc(sizeof(data->r) * data->width * data->height);
data->g = malloc(sizeof(data->g) * data->width * data->height);
data->b = malloc(sizeof(data->b) * data->width * data->height);
}
#define BUFFER_LEN 1024
int load_image(const char *filename, image* data) {
FILE *f = fopen(filename, "r");
char buffer[BUFFER_LEN]; /* read buffer */
size_t max_value;
size_t i;
fgets(buffer, BUFFER_LEN, f);
if (strncmp(buffer, "P3", 2) != 0) {
printf("File begins with %s instead of P3\n", buffer);
return 0;
}
fscanf(f, "%u", &data->width);
fscanf(f, "%u", &data->height);
fscanf(f, "%u", &max_value);
assert(max_value==255);
init_image(data, data->width, data->height);
for (i = 0; i < data->width * data->height; i++) {
fscanf(f, "%hhu", &(data->r[i]));
fscanf(f, "%hhu", &(data->g[i]));
fscanf(f, "%hhu", &(data->b[i]));
}
fclose(f);
printf("Read %zux%zu pixels from %s.\n", data->width, data->height, filename);
}
int write_image(const char *filename, image *data) {
FILE *f = fopen(filename, "w");
size_t i;
fprintf(f, "P3\n%zu %zu\n255\n", data->width, data->height);
for (i = 0; i < data->width * data->height; i++) {
fprintf(f, "%hhu %hhu %hhu ", data->r[i], data->g[i], data->b[i]);
}
fclose(f);
}
unsigned char average(unsigned char *data, size_t data_len) {
size_t i;
size_t j;
size_t hist[256];
for (i = 0; i < 256; i++) hist[i] = 0;
for (i = 0; i < data_len; i++) hist[data[i]]++;
j = 0;
for (i = 0; i < 256; i++) {
j += hist[i];
if (j >= data_len / 2) return i;
}
return 255;
}
void set_pixel(image *data, size_t x, size_t y, unsigned char r, unsigned char g, unsigned char b) {
data->r[x + data->width * y] = r;
data->g[x + data->width * y] = g;
data->b[x + data->width * y] = b;
}
color get_pixel(image *data, size_t x, size_t y) {
color ret;
ret.r = data->r[x + data->width * y];
ret.g = data->g[x + data->width * y];
ret.b = data->b[x + data->width * y];
return ret;
}
void fill(image *data, unsigned char r, unsigned char g, unsigned char b) {
size_t i;
for (i = 0; i < data->width * data->height; i++) {
data->r[i] = r;
data->g[i] = g;
data->b[i] = b;
}
}
void line(image *data, size_t x1, size_t y1, size_t x2, size_t y2, unsigned char r, unsigned char g, unsigned char b) {
size_t x, y, t, pdx, pdy, ddx, ddy, es, el;
int dx, dy, incx, incy, err;
dx=x2-x1;
dy=y2-y1;
incx=SIGN(dx);
incy=SIGN(dy);
if(dx<0) dx=-dx;
if(dy<0) dy=-dy;
if (dx>dy) {
pdx=incx;
pdy=0;
ddx=incx;
ddy=incy;
es=dy;
el=dx;
} else {
pdx=0;
pdy=incy;
ddx=incx;
ddy=incy;
es=dx;
el=dy;
}
x=x1;
y=y1;
err=el/2;
set_pixel(data, x, y, r, g, b);
for(t=0; t<el; t++) {
err -= es;
if(err<0) {
err+=el;
x+=ddx;
y+=ddy;
} else {
x+=pdx;
y+=pdy;
}
set_pixel(data, x, y, r, g, b);
}
}
color average_line(image *data, size_t x1, size_t y1, size_t x2, size_t y2) {
size_t x, y, t, pdx, pdy, ddx, ddy, es, el;
int dx, dy, incx, incy, err;
color ret;
color px;
size_t i;
size_t j;
size_t hist_r[256];
size_t hist_g[256];
size_t hist_b[256];
size_t data_len = 0;
for (i = 0; i < 256; i++) {
hist_r[i] = 0;
hist_g[i] = 0;
hist_b[i] = 0;
}
dx=x2-x1;
dy=y2-y1;
incx=SIGN(dx);
incy=SIGN(dy);
if(dx<0) dx=-dx;
if(dy<0) dy=-dy;
if (dx>dy) {
pdx=incx;
pdy=0;
ddx=incx;
ddy=incy;
es=dy;
el=dx;
} else {
pdx=0;
pdy=incy;
ddx=incx;
ddy=incy;
es=dx;
el=dy;
}
x=x1;
y=y1;
err=el/2;
px = get_pixel(data, x, y);
hist_r[px.r]++;
hist_g[px.g]++;
hist_b[px.b]++;
data_len++;
for(t=0; t<el; t++) {
err -= es;
if(err<0) {
err+=el;
x+=ddx;
y+=ddy;
} else {
x+=pdx;
y+=pdy;
}
px = get_pixel(data, x, y);
hist_r[px.r]++;
hist_g[px.g]++;
hist_b[px.b]++;
data_len++;
}
j = 0;
for (i = 0; i < 256; i++) {
j += hist_r[i];
if (j >= data_len / 2) {
ret.r = i;
break;
}
}
j = 0;
for (i = 0; i < 256; i++) {
j += hist_g[i];
if (j >= data_len / 2) {
ret.g = i;
break;
}
}
j = 0;
for (i = 0; i < 256; i++) {
j += hist_b[i];
if (j >= data_len / 2) {
ret.b = i;
break;
}
}
return ret;
}
void lines(image *source, image *dest, size_t L, float m, float M) {
size_t i, j;
float dx;
float mx, my;
float mm = MAX(MIN(source->width * source->height / L, M), m);
unsigned char av_r = average(source->r, source->width * source->height);
unsigned char av_g = average(source->g, source->width * source->height);
unsigned char av_b = average(source->b, source->width * source->height);
fill(dest, av_r, av_g, av_b);
dx = (float)source->width / L;
mx = 0;
my = mm / 2;
for (i = 0; i < L; i++) {
color avg;
mx += dx;
my += (source->height - mm) / 8;
if (my + mm / 2 > source->height) {
my = mm / 2 + ((size_t)(my + mm / 2) % (size_t)(source->height - mm));
}
avg = average_line(source, mx, my - mm / 2, mx, my + mm / 2);
line(dest, mx, my - mm / 2, mx, my + mm / 2, avg.r, avg.g, avg.b);
}
}
int main(int argc, char *argv[]) {
image source;
image dest;
size_t L;
float m;
float M;
load_image(argv[1], &source);
L = atol(argv[2]);
m = atof(argv[3]);
M = atof(argv[4]);
init_image(&dest, source.width, source.height);
lines(&source, &dest, L, m, M);
write_image(argv[5], &dest);
}
এল = 5000, মি = 10, এম = 50
এল = 5000, মি = 10, এম = 50
এল = 100000, মি = 10, এম = 50