viewer.c
Additions:
make_2x2Halftone();
make_3x3Halftone();
make_3x3Dither();
make_4x4Dither();
make_new_floyd_steinberg();
NEW in Version 0.02!!!
make_blur();
make_negative();
make_posterize();
make_sawtooth();
make_band();
make_contrast();
make_bright();
I made all the new functions operate on COLOR images... cool.
\************************************************************************/
#include <GL/glut.h>
#include <stdio.h>
#define MAXHEIGHT 800
#define MAXWIDTH 800
enum image_type {NORMAL,GRAYSCALE,THRESH,SIMPLE_DIFFUSE,FLOYD_STEINBERG,
TWO_HALF,THREE_HALF,THREE_DITHER,FOUR_DITHER,NEW_FS,
BLUR, NEGATIVE, POSTERIZE, SAWTOOTH, BAND,
CONTRAST, BRIGHT,
NUM_IMAGES} picture_to_draw=NORMAL;
int pic_copy[MAXHEIGHT][MAXWIDTH],width,height,max;
float normal_picture[MAXWIDTH][MAXHEIGHT][3];
GLubyte gray_pictures[NUM_IMAGES][MAXWIDTH][MAXHEIGHT];
float color_pictures[NUM_IMAGES][MAXWIDTH][MAXHEIGHT][3];
char filename[80];
void display(void) {
glClear(GL_COLOR_BUFFER_BIT);
glRasterPos2d(0,0);
switch(picture_to_draw){
case NORMAL:
glutSetWindowTitle(filename);
glDrawPixels(width,height,GL_RGB,GL_FLOAT,normal_picture);
break;
case GRAYSCALE:
glutSetWindowTitle("GrayScale");
glDrawPixels(width,height,GL_LUMINANCE,
GL_UNSIGNED_BYTE,gray_pictures[picture_to_draw]);
break;
case THRESH:
glutSetWindowTitle("Threshold");
glDrawPixels(width,height,GL_LUMINANCE,
GL_UNSIGNED_BYTE,gray_pictures[picture_to_draw]);
break;
case SIMPLE_DIFFUSE:
glutSetWindowTitle("Simple Diffusion");
glDrawPixels(width,height,GL_LUMINANCE,
GL_UNSIGNED_BYTE,gray_pictures[picture_to_draw]);
break;
case FLOYD_STEINBERG:
glutSetWindowTitle("Floyd-Steinberg");
glDrawPixels(width,height,GL_LUMINANCE,
GL_UNSIGNED_BYTE,gray_pictures[picture_to_draw]);
break;
case TWO_HALF:
glDrawPixels(2*width,2*height,
GL_LUMINANCE, GL_UNSIGNED_BYTE,
gray_pictures[picture_to_draw]);
glutSetWindowTitle("2x2 Half-Tone");
break;
case THREE_HALF:
glutSetWindowTitle("3x3 Half-Tone");
glDrawPixels(3*width,3*height,
GL_LUMINANCE,GL_UNSIGNED_BYTE,
gray_pictures[picture_to_draw]);
break;
case THREE_DITHER:
glutSetWindowTitle("3x3Matrix Dither");
glDrawPixels(width,height,GL_LUMINANCE,
GL_UNSIGNED_BYTE,gray_pictures[picture_to_draw]);
break;
case FOUR_DITHER:
glutSetWindowTitle("4x4Matrix Dither");
glDrawPixels(width,height,GL_LUMINANCE,
GL_UNSIGNED_BYTE,gray_pictures[picture_to_draw]);
break;
case NEW_FS:
glutSetWindowTitle("*New* Floyd-Steinberg");
glDrawPixels(width,height,GL_LUMINANCE,
GL_UNSIGNED_BYTE,gray_pictures[picture_to_draw]);
break;
case BLUR:
glutSetWindowTitle("Blur (RGB)");
glDrawPixels(width,height,GL_RGB,GL_FLOAT,color_pictures[picture_to_draw]);
break;
case NEGATIVE:
glutSetWindowTitle("Negative (RGB)");
glDrawPixels(width,height,GL_RGB,GL_FLOAT,color_pictures[picture_to_draw]);
break;
case POSTERIZE:
glutSetWindowTitle("Posterize (RGB)");
glDrawPixels(width,height,GL_RGB,GL_FLOAT,color_pictures[picture_to_draw]);
break;
case SAWTOOTH:
glutSetWindowTitle("Saw-Tooth (RGB)");
glDrawPixels(width,height,GL_RGB,GL_FLOAT,color_pictures[picture_to_draw]);
break;
case BAND:
glutSetWindowTitle("Band (RGB)");
glDrawPixels(width,height,GL_RGB,GL_FLOAT,color_pictures[picture_to_draw]);
break;
case CONTRAST:
glutSetWindowTitle("Contrast (RGB)");
glDrawPixels(width,height,GL_RGB,GL_FLOAT,color_pictures[picture_to_draw]);
break;
case BRIGHT:
glutSetWindowTitle("Brighten (RGB)");
glDrawPixels(width,height,GL_RGB,GL_FLOAT,color_pictures[picture_to_draw]);
break;
}
}
void init (void)
{
glClearColor(1.0, 1.0, 1.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, 1, 0, 1); /*or 0,width,0,height*/
glMatrixMode(GL_MODELVIEW);
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
glPixelStorei(GL_UNPACK_ROW_LENGTH,MAXWIDTH);
}
void keyboard(unsigned char dakey, int x, int y)
{
switch(dakey) {
case 'q': case 'Q': exit(0);
}
}
void make_grayscale()
{
int ii,jj,kk;
float sum;
for(ii=0;ii<height;ii++)
for(jj=0;jj<width;jj++)
{
for(sum=kk=0;kk<3;kk++)
sum += normal_picture[ii][jj][kk]/3;
gray_pictures[GRAYSCALE][ii][jj]=sum*255;
}
}
void make_simplediffuse()
{
int ii,jj,error;
for(ii=0;ii<height;ii++)
for(jj=0;jj<width;jj++)
pic_copy[ii][jj] = gray_pictures[GRAYSCALE][ii][jj];
for(ii=0;ii<height;ii++)
for(jj=0;jj<width;jj++)
{
gray_pictures[SIMPLE_DIFFUSE][ii][jj] =
(pic_copy[ii][jj]<128) ? 0 : 255;
error = pic_copy[ii][jj] -
gray_pictures[SIMPLE_DIFFUSE][ii][jj];
pic_copy[ii][jj+1] += error;
}
}
void make_thresh()
{
int ii,jj;
for(ii=0;ii<height;ii++)
for(jj=0;jj<width;jj++)
gray_pictures[THRESH][ii][jj] =
(gray_pictures[GRAYSCALE][ii][jj]<128) ? 0 : 255;
}
void make_floyd_steinberg()
{
int ii,jj,error;
for(ii=0;ii<height-1;ii++)
for(jj=0;jj<width-1;jj++)
pic_copy[ii][jj] = gray_pictures[GRAYSCALE][ii][jj];
for(ii=0;ii<height-1;ii++)
for(jj=0;jj<width-1;jj++)
{
gray_pictures[FLOYD_STEINBERG][ii][jj] =
(pic_copy[ii][jj]<128) ? 0 : 255;
error = pic_copy[ii][jj] -
gray_pictures[FLOYD_STEINBERG][ii][jj];
pic_copy[ii][jj+1] += error*7.0/16;
pic_copy[ii+1][jj+1] += error*1.0/16;
pic_copy[ii+1][jj] += error*5.0/16;
pic_copy[ii+1][jj-1] += error*3.0/16;
}
}
/*************************************************************************
My code...
\************************/
void make_2x2Halftone(void) {
/* each single pixel in pic_copy sets 4 pixels in **
** graypictures[TWO_HALF] **************************/
/* 0% = 0, 33% = 84, 66% = 153, 100% = 255 */
int ii,jj,outii,outjj;
for(ii=0;ii<height;ii++)
for(jj=0;jj<width;jj++)
pic_copy[ii][jj] = gray_pictures[GRAYSCALE][ii][jj];
outii = 0; outjj = 0;
for(ii=0;ii<height;ii++){
for(jj=0;jj<width;jj++) {
if (pic_copy[ii][jj] > 61){
if(pic_copy[ii][jj] > 127){
if(pic_copy[ii][jj] > 191){
/* > 75%% */
gray_pictures[TWO_HALF][outii][outjj] = 255;
gray_pictures[TWO_HALF][outii+1][outjj] = 255;
gray_pictures[TWO_HALF][outii][outjj+1] = 255;
gray_pictures[TWO_HALF][outii+1][outjj+1] = 255;
}
else{
/* > 50% */
gray_pictures[TWO_HALF][outii][outjj] = 0;
gray_pictures[TWO_HALF][outii+1][outjj] = 255;
gray_pictures[TWO_HALF][outii][outjj+1] = 255;
gray_pictures[TWO_HALF][outii+1][outjj+1] = 255;
}
}
else{
/* > 25% */
gray_pictures[TWO_HALF][outii][outjj] = 0;
gray_pictures[TWO_HALF][outii+1][outjj] = 255;
gray_pictures[TWO_HALF][outii][outjj+1] = 255;
gray_pictures[TWO_HALF][outii+1][outjj+1] = 0;
}
}
else{
/* > 0% */
gray_pictures[TWO_HALF][outii][outjj] = 0;
gray_pictures[TWO_HALF][outii+1][outjj] = 0;
gray_pictures[TWO_HALF][outii][outjj+1] = 0;
gray_pictures[TWO_HALF][outii+1][outjj+1] = 0;
}
outjj = 2*jj; /* increment by 2 */
if((outii > MAXHEIGHT)&&(outjj > MAXWIDTH)){ break; }
}/* inner for loop */
outii = 2*ii;
}/* outer for loop */
}
void make_3x3Halftone(void) {
/* each single pixel in pic_copy sets 9 pixels in **
** graypictures[TWO_HALF] **************************/
/* 0% = 0, 10% = 25 ect.. */
int ii,jj,outii,outjj;
for(ii=0;ii<height;ii++)
for(jj=0;jj<width;jj++)
pic_copy[ii][jj] = gray_pictures[GRAYSCALE][ii][jj];
outii = 0; outjj = 0;
for(ii=0;ii<height;ii++){
for(jj=0;jj<width;jj++) {
if((pic_copy[ii][jj] >= 0)&&(pic_copy[ii][jj] < 25)){
/* > 0% */
gray_pictures[THREE_HALF][outii] [outjj] = 0;
gray_pictures[THREE_HALF][outii+1][outjj] = 0;
gray_pictures[THREE_HALF][outii+2][outjj] = 0;
gray_pictures[THREE_HALF][outii] [outjj+1] = 0;
gray_pictures[THREE_HALF][outii+1][outjj+1] = 0;
gray_pictures[THREE_HALF][outii+2][outjj+1] = 0;
gray_pictures[THREE_HALF][outii] [outjj+2] = 0;
gray_pictures[THREE_HALF][outii+1][outjj+2] = 0;
gray_pictures[THREE_HALF][outii+2][outjj+2] = 0;
}
else if ((pic_copy[ii][jj] >= 25)&&(pic_copy[ii][jj] < 50)) {
/* > 10% */
gray_pictures[THREE_HALF][outii] [outjj] = 0;
gray_pictures[THREE_HALF][outii+1][outjj] = 0;
gray_pictures[THREE_HALF][outii+2][outjj] = 0;
gray_pictures[THREE_HALF][outii] [outjj+1] = 0;
gray_pictures[THREE_HALF][outii+1][outjj+1] = 255;
gray_pictures[THREE_HALF][outii+2][outjj+1] = 0;
gray_pictures[THREE_HALF][outii] [outjj+2] = 0;
gray_pictures[THREE_HALF][outii+1][outjj+2] = 0;
gray_pictures[THREE_HALF][outii+2][outjj+2] = 0;
}
else if ((pic_copy[ii][jj] >= 50)&&(pic_copy[ii][jj] < 75)) {
/* > 20% */
gray_pictures[THREE_HALF][outii] [outjj] = 0;
gray_pictures[THREE_HALF][outii+1][outjj] = 255;
gray_pictures[THREE_HALF][outii+2][outjj] = 0;
gray_pictures[THREE_HALF][outii] [outjj+1] = 0;
gray_pictures[THREE_HALF][outii+1][outjj+1] = 0;
gray_pictures[THREE_HALF][outii+2][outjj+1] = 0;
gray_pictures[THREE_HALF][outii] [outjj+2] = 0;
gray_pictures[THREE_HALF][outii+1][outjj+2] = 255;
gray_pictures[THREE_HALF][outii+2][outjj+2] = 0;
}
else if ((pic_copy[ii][jj] >= 75)&&(pic_copy[ii][jj] < 100)) {
/* > 30% */
gray_pictures[THREE_HALF][outii] [outjj] = 255;
gray_pictures[THREE_HALF][outii+1][outjj] = 0;
gray_pictures[THREE_HALF][outii+2][outjj] = 0;
gray_pictures[THREE_HALF][outii] [outjj+1] = 0;
gray_pictures[THREE_HALF][outii+1][outjj+1] = 255;
gray_pictures[THREE_HALF][outii+2][outjj+1] = 0;
gray_pictures[THREE_HALF][outii] [outjj+2] = 0;
gray_pictures[THREE_HALF][outii+1][outjj+2] = 255;
gray_pictures[THREE_HALF][outii+2][outjj+2] = 0;
}
else if ((pic_copy[ii][jj] >= 100)&&(pic_copy[ii][jj] < 125)) {
/* > 40% */
gray_pictures[THREE_HALF][outii] [outjj] = 0;
gray_pictures[THREE_HALF][outii+1][outjj] = 255;
gray_pictures[THREE_HALF][outii+2][outjj] = 0;
gray_pictures[THREE_HALF][outii] [outjj+1] = 0;
gray_pictures[THREE_HALF][outii+1][outjj+1] = 255;
gray_pictures[THREE_HALF][outii+2][outjj+1] = 255;
gray_pictures[THREE_HALF][outii] [outjj+2] = 0;
gray_pictures[THREE_HALF][outii+1][outjj+2] = 0;
gray_pictures[THREE_HALF][outii+2][outjj+2] = 255;
}
else if ((pic_copy[ii][jj] >= 125)&&(pic_copy[ii][jj] < 150)) {
/* > 50% */
gray_pictures[THREE_HALF][outii] [outjj] = 255;
gray_pictures[THREE_HALF][outii+1][outjj] = 0;
gray_pictures[THREE_HALF][outii+2][outjj] = 255;
gray_pictures[THREE_HALF][outii] [outjj+1] = 0;
gray_pictures[THREE_HALF][outii+1][outjj+1] = 255;
gray_pictures[THREE_HALF][outii+2][outjj+1] = 0;
gray_pictures[THREE_HALF][outii] [outjj+2] = 255;
gray_pictures[THREE_HALF][outii+1][outjj+2] = 0;
gray_pictures[THREE_HALF][outii+2][outjj+2] = 255;
}
else if ((pic_copy[ii][jj] >= 150)&&(pic_copy[ii][jj] < 175)) {
/* > 60% */
gray_pictures[THREE_HALF][outii] [outjj] = 0;
gray_pictures[THREE_HALF][outii+1][outjj] = 255;
gray_pictures[THREE_HALF][outii+2][outjj] = 255;
gray_pictures[THREE_HALF][outii] [outjj+1] = 255;
gray_pictures[THREE_HALF][outii+1][outjj+1] = 0;
gray_pictures[THREE_HALF][outii+2][outjj+1] = 255;
gray_pictures[THREE_HALF][outii] [outjj+2] = 0;
gray_pictures[THREE_HALF][outii+1][outjj+2] = 255;
gray_pictures[THREE_HALF][outii+2][outjj+2] = 255;
}
else if ((pic_copy[ii][jj] >= 175)&&(pic_copy[ii][jj] < 200)) {
/* > 70% */
gray_pictures[THREE_HALF][outii] [outjj] = 255;
gray_pictures[THREE_HALF][outii+1][outjj] = 255;
gray_pictures[THREE_HALF][outii+2][outjj] = 255;
gray_pictures[THREE_HALF][outii] [outjj+1] = 0;
gray_pictures[THREE_HALF][outii+1][outjj+1] = 255;
gray_pictures[THREE_HALF][outii+2][outjj+1] = 255;
gray_pictures[THREE_HALF][outii] [outjj+2] = 255;
gray_pictures[THREE_HALF][outii+1][outjj+2] = 0;
gray_pictures[THREE_HALF][outii+2][outjj+2] = 255;
}
else if ((pic_copy[ii][jj] >= 200)&&(pic_copy[ii][jj] < 225)) {
/* > 80% */
gray_pictures[THREE_HALF][outii] [outjj] = 255;
gray_pictures[THREE_HALF][outii+1][outjj] = 255;
gray_pictures[THREE_HALF][outii+2][outjj] = 255;
gray_pictures[THREE_HALF][outii] [outjj+1] = 0;
gray_pictures[THREE_HALF][outii+1][outjj+1] = 255;
gray_pictures[THREE_HALF][outii+2][outjj+1] = 255;
gray_pictures[THREE_HALF][outii] [outjj+2] = 255;
gray_pictures[THREE_HALF][outii+1][outjj+2] = 255;
gray_pictures[THREE_HALF][outii+2][outjj+2] = 255;
}
else{
/* > 90% */
gray_pictures[THREE_HALF][outii] [outjj] = 255;
gray_pictures[THREE_HALF][outii+1][outjj] = 255;
gray_pictures[THREE_HALF][outii+2][outjj] = 255;
gray_pictures[THREE_HALF][outii] [outjj+1] = 255;
gray_pictures[THREE_HALF][outii+1][outjj+1] = 255;
gray_pictures[THREE_HALF][outii+2][outjj+1] = 255;
gray_pictures[THREE_HALF][outii] [outjj+2] = 255;
gray_pictures[THREE_HALF][outii+1][outjj+2] = 255;
gray_pictures[THREE_HALF][outii+2][outjj+2] = 255;
}
outjj = 3*jj; /* increment by 2 */
if((outii > MAXHEIGHT)&&(outjj > MAXWIDTH)){ break; }
}/* inner for loop */
outii = 3*ii;
}/* outer for loop */
}
void make_3x3Dither(){
float II;
int ii, jj, Di, Dj, nn;
int Dm[3][3] = {{7,2,6}
,{4,0,1}
,{3,8,5}};
nn = 3;
/* xx = 9/255; = 0.03529411 */
for(ii=0;ii<height;ii++){
for(jj=0;jj<width;jj++){
pic_copy[ii][jj] = gray_pictures[GRAYSCALE][ii][jj];
}
}
for(ii=0; ii<height; ii++){
Di = ii % nn;
for(jj=0; jj<width; jj++){
Dj = jj % nn; /* bounded by nn */
II = (0.03529411) * pic_copy[ii][jj];
/* scale Intensity */
/*
printf( "xx = %d ,", xx);
printf( "Dm: %i ,", Dm[Di][Dj]);
printf( "II(x,y): %i , ", II);
printf( "I(pic): %i , ", pic_copy[ii][jj]);
printf ("-> written to: [(%i,%i) , (%i,%i)];\n", ii,jj,Di,Dj);
//*/
if(II >= Dm[Di][Dj]){ gray_pictures[THREE_DITHER][ii][jj] = 255; }
else { gray_pictures[THREE_DITHER][ii][jj] = 0; }
} /* inner for loop */
} /* outer for loop */
}
void make_4x4Dither(){
float II;
int ii, jj, Di, Dj, nn;
int Dm[4][4] = {{ 7,15, 6, 9}
,{13,10, 0,12}
,{ 3, 8,11, 5}
,{ 1, 4,14, 2}};
nn = 4;
/* xx = 16/255; = 0.06274509803922 */
for(ii=0;ii<height;ii++){
for(jj=0;jj<width;jj++){
pic_copy[ii][jj] = gray_pictures[GRAYSCALE][ii][jj];
}
}
for(ii=0; ii<height; ii++){
Di = ii % nn;
for(jj=0; jj<width; jj++){
Dj = jj % nn; /* bounded by nn */
II = (0.06274509803922) * pic_copy[ii][jj];
/* scale Intensity */
if(II >= Dm[Di][Dj]){ gray_pictures[FOUR_DITHER][ii][jj] = 255; }
else { gray_pictures[FOUR_DITHER][ii][jj] = 0; }
} /* inner for loop */
} /* outer for loop */
}
void make_new_floyd_steinberg()
{
int ii,jj,error;
for(ii=0;ii<height-1;ii++)
for(jj=0;jj<width-1;jj++)
pic_copy[ii][jj] = gray_pictures[GRAYSCALE][ii][jj];
for(ii=0;ii<height;ii++){
for(jj=0;jj<width;jj++) {
if((ii < height-1)&&(jj < width -1)){
gray_pictures[NEW_FS][ii][jj] =
(pic_copy[ii][jj]<128) ? 0 : 255;
error = pic_copy[ii][jj] -
gray_pictures[NEW_FS][ii][jj];
pic_copy[ii][jj+1] += error*7.0/16;
pic_copy[ii+1][jj+1] += error*1.0/16;
pic_copy[ii+1][jj] += error*5.0/16;
pic_copy[ii+1][jj-1] += error*3.0/16;
}
else if(ii < height-1){
gray_pictures[NEW_FS][ii][jj] =
(pic_copy[ii][jj]<128) ? 0 : 255;
error = pic_copy[ii][jj] -
gray_pictures[NEW_FS][ii][jj];
pic_copy[ii][jj+1] += error*7.0/16;
pic_copy[0][jj+1] += error*1.0/16;
pic_copy[0][jj] += error*5.0/16;
pic_copy[0][jj-1] += error*3.0/16;
}
else if(jj < width-1){
gray_pictures[NEW_FS][ii][jj] =
(pic_copy[ii][jj]<128) ? 0 : 255;
error = pic_copy[ii][jj] -
gray_pictures[NEW_FS][ii][jj];
pic_copy[ii][0] += error*7.0/16;
pic_copy[ii+1][0] += error*1.0/16;
pic_copy[ii+1][jj] += error*5.0/16;
pic_copy[ii+1][jj-1] += error*3.0/16;
}
else{
gray_pictures[NEW_FS][ii][jj] =
(pic_copy[ii][jj]<128) ? 0 : 255;
error = pic_copy[ii][jj] -
gray_pictures[NEW_FS][ii][jj];
}
} /* inner for loop*/
} /* outer for loop*/
}
/* Color filters ** Color filters */
void make_blur() {
int ii,jj,kk,pix;
float sum;
pix = 9;
for(ii=0;ii<height;ii++){
for(jj=0;jj<width;jj++) {
for(kk=0; kk<3; kk++){
sum = 0;
if((ii-1>=0)&&(jj-1>=0)) {sum += normal_picture[ii-1][jj-1][kk];} /* 1 */
if(jj-1>=0) {sum += normal_picture[ii ][jj-1][kk];} /* 2 */
if((ii+1<=height)&&(jj-1>=0)) {sum += normal_picture[ii+1][jj-1][kk];} /* 3 */
if(ii-1>=0) {sum += normal_picture[ii-1][jj ][kk];} /* 4 */
sum += normal_picture[ii ][jj ][kk]; /* 5 */
if(ii+1<=height) {sum += normal_picture[ii+1][jj ][kk];} /* 6 */
if((ii-1>=0)&&(jj+1<=width)) {sum += normal_picture[ii-1][jj+1][kk];} /* 7 */
if((ii-1>0)&&(jj+1<=width)) {sum += normal_picture[ii ][jj+1][kk];} /* 8 */
if((ii-1>0)&&(jj+1<=width)) {sum += normal_picture[ii+1][jj+1][kk];} /* 9 */
color_pictures[BLUR][ii][jj][kk] = sum / pix; /* averaged */
}/* inner most for loop */
}/* middle for loop */
}/* outer for loop */
}
void make_negative() {
int ii,jj,kk;
for(ii=0;ii<height;ii++){
for(jj=0;jj<width;jj++) {
for(kk=0; kk<3; kk++){
color_pictures[NEGATIVE][ii][jj][kk] = 1 - normal_picture[ii][jj][kk];
}/* inner most for loop */
}/* middle for loop */
}/* outer for loop */
}
void make_posterize() {
int ii,jj,kk;
float value, thresh;
thresh = 0.25; /* so I can alter the threshold */
for(ii=0;ii<height;ii++){
for(jj=0;jj<width;jj++) {
for(kk=0; kk<3; kk++){
value = normal_picture[ii][jj][kk];
if(value > 0){
if(value > thresh ){
if(value > 2*thresh){
if(value > 3*thresh){
color_pictures[POSTERIZE][ii][jj][kk] = 4 * thresh;
}
else color_pictures[POSTERIZE][ii][jj][kk] = 3 * thresh;
}
else color_pictures[POSTERIZE][ii][jj][kk] = 2 * thresh;
}
else color_pictures[POSTERIZE][ii][jj][kk] = thresh;
}
else color_pictures[POSTERIZE][ii][jj][kk] = 0;
/*read backwards... colors trickle up... (no complex tests)*/
}/* inner most for loop */
}/* middle for loop */
}/* outer for loop */
}
void make_sawtooth() {
int ii,jj,kk;
float value, new_value;
for(ii=0;ii<height;ii++){
for(jj=0;jj<width;jj++) {
for(kk=0; kk<3; kk++){
value = normal_picture[ii][jj][kk];
/* color_pictures[SAWTOOTH][ii][jj][kk] = normal_picture[ii][jj][kk]; */
new_value = value * 0.33;
if(value > 0){
if(value > 0.33){
if(value > (2*0.33)){
color_pictures[SAWTOOTH][ii][jj][kk] = 4 * new_value;
}
else color_pictures[SAWTOOTH][ii][jj][kk] = 3 * new_value;
}
else color_pictures[SAWTOOTH][ii][jj][kk] = 2 * new_value;
}
else color_pictures[SAWTOOTH][ii][jj][kk] = new_value;
/* colors trickle up... no complex tests... */
}/* inner most for loop */
}/* middle for loop */
}/* outer for loop */
}
void make_band() {
int ii,jj,kk;
float value;
for(ii=0;ii<height;ii++){
for(jj=0;jj<width;jj++) {
for(kk=0; kk<3; kk++){
value = normal_picture[ii][jj][kk];
/* color_pictures[NEGATIVE][ii][jj][kk] = 1 - normal_picture[ii][jj][kk];*/
if((value >= 0.25) && (value <= 0.45))
color_pictures[BAND][ii][jj][kk] = value;
else if((value >= 0.75) && (value <= 0.95))
color_pictures[BAND][ii][jj][kk] = value;
else
color_pictures[BAND][ii][jj][kk] = 0;
}/* inner most for loop */
}/* middle for loop */
}/* outer for loop */
}
/******* CONTRAST, BRIGHT**************/
void make_contrast() {
int ii,jj,kk;
for(ii=0;ii<height;ii++){
for(jj=0;jj<width;jj++) {
for(kk=0; kk<3; kk++){
color_pictures[CONTRAST][ii][jj][kk] = (normal_picture[ii][jj][kk] * 1.25);
}/* inner most for loop */
}/* middle for loop */
}/* outer for loop */
}
void make_bright() {
int ii,jj,kk;
for(ii=0;ii<height;ii++){
for(jj=0;jj<width;jj++) {
for(kk=0; kk<3; kk++){
color_pictures[BRIGHT][ii][jj][kk] = normal_picture[ii][jj][kk] + 0.25;
}/* inner most for loop */
}/* middle for loop */
}/* outer for loop */
}
/************************\
End of Code.
\*************************************************************************/
void readppmfile()
{
char line[80];
int ii,jj,kk,temp;
FILE *infile;
if ( !(infile = fopen(filename,"r")))
{
fprintf(stderr,"Unable to open data file: %s.\n",filename);
exit(1);
}
fgets(line,80,infile);
if(line[0]!='P' || line[1] != '3')
{
fprintf(stderr,"Not a ppm 3 file.\n");
exit(1);
}
while((temp = getc(infile)) == '#')
{
fgets(line,80,infile);
printf("Picture comment: %s",line);
}
ungetc(temp,infile);
fscanf(infile,"%d %d %d",&width,&height,&max);
printf("%d by %d, max value %d.\n",width,height,max);
if(width>MAXWIDTH || height>MAXHEIGHT)
{
printf("Picture too big in some dimension.\n");
printf("Increase MAXWIDTH and/or MAXHEIGHT and recompile.\n");
exit(1);
}
for(ii=height-1;ii>=0;ii--)
for(jj=0;jj<width;jj++)
for(kk=0;kk<3;kk++)
{
fscanf(infile,"%d",&temp);
normal_picture[ii][jj][kk] = ((float) temp)/max;
}
}
void handle_menu(int value) {
if(value==NUM_IMAGES) exit(0);
picture_to_draw = value;
if(picture_to_draw==TWO_HALF)
glutReshapeWindow(2*width, 2*height);
else if(picture_to_draw==THREE_HALF)
glutReshapeWindow(3*width, 3*height);
else
glutReshapeWindow(width, height);
glutPostRedisplay();
}
int main(int argc, char** argv)
{
int Color, BnW;
strcpy(filename, ( (argc==2) ? argv[1] : "mandril.ppm"));
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
readppmfile();
make_grayscale();
make_thresh();
make_simplediffuse();
make_floyd_steinberg();
make_2x2Halftone();
make_3x3Halftone();
make_3x3Dither();
make_4x4Dither();
make_new_floyd_steinberg();
make_blur();
make_negative();
make_posterize();
make_sawtooth();
make_band();
make_contrast();
make_bright();
glutInitWindowSize (width, height);
glutInitWindowPosition (100, 100);
glutCreateWindow ("ppm reader");
init();
glutKeyboardFunc(keyboard);
glutDisplayFunc(display);
BnW = glutCreateMenu(handle_menu);
glutAddMenuEntry("Grayscale",GRAYSCALE);
glutAddMenuEntry("Threshold",THRESH);
glutAddMenuEntry("Simple error diffusion",SIMPLE_DIFFUSE);
glutAddMenuEntry("Floyd-Steinberg",FLOYD_STEINBERG);
glutAddMenuEntry("2x2Half-Tone",TWO_HALF);
glutAddMenuEntry("3x3Half-Tone",THREE_HALF);
glutAddMenuEntry("3x3Matrix Dither",THREE_DITHER);
glutAddMenuEntry("4x4Matrix Dither",FOUR_DITHER);
glutAddMenuEntry("New Floyd-Steinberg",NEW_FS);
Color = glutCreateMenu(handle_menu);
glutAddMenuEntry("Blur",BLUR);
glutAddMenuEntry("Negative", NEGATIVE);
glutAddMenuEntry("Posterize",POSTERIZE);
glutAddMenuEntry("SawTooth", SAWTOOTH);
glutAddMenuEntry("Arbitrary Band",BAND);
glutAddMenuEntry("Contrast", CONTRAST);
glutAddMenuEntry("Brighten", BRIGHT);
glutCreateMenu(handle_menu);
glutAddMenuEntry(filename,NORMAL);
glutAddSubMenu("B/W Filters", BnW);
glutAddSubMenu("Color Filters", Color);
glutAddMenuEntry("Quit",NUM_IMAGES);
glutAttachMenu(GLUT_RIGHT_BUTTON);
glutMainLoop();
return 0; /* ANSI C requires main to return int. */
}