From oleg@ponder.csci.unt.edu Sun Jul 3 12:25:47 1994 From: oleg@ponder.csci.unt.edu (Kiselyov Oleg) Newsgroups: comp.lang.c++,comp.graphics,alt.graphics.pixutils,comp.sys.mac.programmer Subject: grayimage C++ classlib posted to comp.sources.misc Date: 30 Jun 1994 15:19:45 -0500 Organization: University of North Texas Reply-To: oleg@ponder.csci.unt.edu NNTP-Posting-Host: sparky.sterling.com Summary: grayscale image processing class library and verification code Keywords: grayscale, image processing, C++, class library Environment: C++, tested_on{G++ 2.2.2+, Symantec 6.0.1+, Sun, HP, Mac, Sequent} This package has just been posted to comp.sources.misc. grayimage_classlib is a C++ class library to do a generic processing of grayscale images. It is one part of my image compression code I've been messing with for almost 3 years. This part is general enough to be of some interest to folks at large (I hope). It lets you do a variety of different operations on images, rectangular areas, etc: say, add two images, compute their "scalar product", modify pixel values over the entire image or some rectangular area of it in a _variety_ of ways, equalize the image histogram, stuff like that. One function, shift_clip_add(), does actually the filtration (convolution). Morphological filtration is implemented as well. I tried to make the code as optimal as I could think of (without getting into assembly -:). The package can read/write XWD, Group G TIFF and PGM file formats; actually, the package understands which file format it's asked to read and selects the appropriate method automatically. I demonstrated pieces at Data Compression Conferences, and some people suggested me submit it into the public domain. The file images.dr tells exactly which modules are in the package and what they are good for. There are several v*.cc files in the package: these are verification files, you can compile them and run to make sure everything works as it's supposed to. The validation files can also be used as an example as to how to use the package (because they test, that is, use all the constructions/classes /functions /methods of the package, and not once 8:) The package has been compiled with gcc/g++ version 2.2.2 and later on Sun Sparc/SunOS, HP 9000, Sequent Symmetry/Dynix, Concurrent/RTU, and with Symantec C++ 6.0.1 (through 7.0.2) on Mac. The package has been in operation for 2.5 years. I also have to mention that the image package I'm submitting is just the very bottom layer of the image and video processing stuff I've been working on. The bottom layer is meant to give the basic working environment rather to do something fancy with the image (though, BTW, function shift_clip_add() makes the convolution in two stmts; and this lets you do a whole lot of the fancy things in the digital darkroom). So, there is much more to the story. BTW, it also means that I'm constantly adding to the package (as I come across a need for some function, option, etc), so your comments/suggestions will be highly appreciated. And now, here's a quick glance at the package capabilities: // Note! This is the *correct* code; Put it within main(){}, and it will // compile, run and finish without errors // Pixel operations IMAGE im1(256,256,8); IMAGE im2(im1); im1 = 1; im2 = im1; im1 *= 4; // Assigning a value to every pixel assert( im1 == 4 ); assert( im1 >0 ); // Checking up the value of every pixel im1.invert(); im1.clear(); im2 <<= 2; im1 = 5; im1 &= 0xfe; assert( im1==im2); // Modifying every pixel im1.clear(); im1 -= im2; im2 = im1; // Subtracting two images // Applying *any* function to every im1.abs(); im2.apply(::abs); assert(im1 == im2); // pixel (abs() in the ex.) assert( im1 * im1 == norm_2_sqr(im1) ); // Computing the "scalar product" // and image norm // Square and rectangular parts of image im1 = 2*pattern; im2 = pattern; rowcol rightbottom(im1.q_nrows()-1,im1.q_ncols()-1); rowcol center(im1.q_nrows()/2,im1.q_ncols()/2); // Modifying pixels only within the // lower left quadrant im1.rectangle(center,rightbottom) -= 2*pattern; assert( !(im1 == 2*pattern) && !(im1 != 2*pattern) ); // Another way of doing this im1.shift_clip_add(center,2,im2); assert(im1 == 2*pattern); // Miscellanea // Note "expanded" file name of the // image IMAGE raw_image("zcat ../../pictures/lenna.xwd.Z |"); // IMAGE image(IMAGE::Shrink,raw_image); IMAGE image = raw_image.square_of(256,rowcol(120,100)); image.write("/tmp/ior","Original image"); image.display("Image to display");