Development Log

Week 1: January 15-January 20

Tuesday, 15 January:
Received project assignment. Initial trepidation was followed buy inspiring visions
of algorithms that could possibly be used. I immediately recognized the problem of using VC++ with MFC,
along with decompressing JPEGs.
 

Wednesday, 16 January:

Researched info on the Internet concerning the file structure and compression/decompression
of JPEGs. Saved one webpage depicting the file structure of the JPEG, complete with hexadecimal byte values
that indicated where segments of the file started and finished.
 

Thursday, 17 January:

Researched info on the Internet concerning the structure of Bitmap files and how
to read them. Obtained sample code in C which read a bitmap and drew it on the screen.
 

Friday, 18 January:

Began forays into the world of MFC programming. I found the website www.relisoft.com,
which offered tutorials in MFC and API programming. Internet sources not sufficient at this time. Must
contact Dr. McVey to borrow copy of CS 350 textbook(s), and other related material I can borrow. I also
began to form the Plan of Attack, which will begin with developing the Windows interface. Plan of Attack
to be finalized on Monday, and submitted for approval at next meeting.
 

Saturday/Sunday 19-20 January:

Further pondered options and strategies for Plan of Attack.
 

Week 2: January 21-January 27

Monday, January 21:

Completed my resume, career path statement, and statemtent of CS philosophy
 

Tuesday, January 22:

Learned what other people are doing for projects. I consider myself fortunate that
I have a mere software devolopment project, and do not have to implement controls, etc. on trains and robots. I also
learned HTML in lab, which is great fun....
 

Friday, January 25:

Recieved MFC textbooks and CDROMS from Dr. McVey. Read two chapters of the Deitel
text, and understood the basics (I think). I will try it out tomorrow...
 

Saturday, January 26:

Successfully compiled example program from text, also played around with window
size. Also studied Deitel text more to glean more info on buttons, menus, etc...
 

Sunday, January 27:

Successfully wrote and compiled first version of the interface. At this time,
it is just a blank window, but I understand how the class hierarchy works in MFC. In Prosise text, I found
definitive info on making push-buttons in a frame window. Must study further...
 

Week 3: January 28-February 3

Monday, January 28:

Studied the MFC CButton class, and implemented a single button in my bare frame window. Clicking on the button produced a message box which indicated that the button was clicked. At this point, I am still debating whether to actually include push buttons in the frame window, use a user-drawn toolbar, or use a menu-driven program that uses dialog boxes and child windows....
 

Tuesday, January 29:

Looked at Microsoft Photo Editor in order to receive inspiration as to how to design my interface. I recognized the neatness and efficiency of a menu-driven application, and began to ponder the possibilities ....
 

Wednesday, January 30:

Heavy research into Prosise and Deitel texts to determine how to make a menu. In the evening, I came near to completion. I had all the menu definitions, message handlers, and handler functions defined and ready to go, but had trouble with mymenu.rc and resource.h. Ran out of time around midnight....
 

Thursday, January 31:

Menu implementation is successful. All image editing functions I wrote at this time spit out a message box when called from the menu. The problem from last night was that I did not include resource.h in the interface2.cpp source code. I came to that conclusion upon studying the infamous NASA program from CS 205. Thank you Professor Blahnik! Webpage update also on today's agenda, as well as studying predefined File-menu dialog boxes from classes in "afxdlgs.h".... A screen capture may be up this weekend ....
 

Sunday, February 3:

Implemented Open and SaveAs dialog boxes. Need to create custom boxes for brightness/contrast control, zooming, and rotate functions. In this next week, I must finish the interface, create a data structure for the pixels, and read a bitmap file into this data structure and display it on the screen. I must get a design for this structure on paper and discuss the path from here with DCP this week. I would also like to show Dr. McVey my source code for the interface and get her opinion as to its design.
 

Week 4: February 4 - February 10

Monday, February 4:

Attempted to implement a custom dialog box in my interface. First attempts were met with frustration, as I had omitted necessary function calls to create and show the dialog box in the main window. Later that day, I was successful using ShowWindow() in my code.
 

Tuesday, February 5:

Today, I gave the class an update on how far I had come in my project. I appear to be farther along than others, but not as far as the "superstars" in the class (you know who you are...). Once again, I am in the middle of the pack... Scrutinized the Prosise text for more tips on using dialog boxes and more importantly the structures associated with the Windows Bitmap image file.
 

Wednesday, February 6:

I did extensive research on the Internet regarding the methods used to read and manipulate Bitmap files. One webpage written by Ahmad Hafiz gave detailed info about Windows bitmap files. Apparently, they are divided into 4 sections: File Header, Info Header, Palette, and Image Data. Reading the bitmap seems a relatively easy task once the developer uses C structs to classify the header data. I am still fuzzy on what a "palette" is and why it is needed in Bitmap files. I saw no mention of palettes in the JPEG material I ran across. No matter, though, as I am excited to finally be gettin' down in the "nitty-gritty" of this project!
 

Thursday, February 7:

In the morning, I examined my MFC text for an explanation of what a palette is and why it exists. Apparently, a palette is just the set of unique colors that an image is constructed from. A palette is enclosed within a file to ensure that the application displaying it does so with the appropriate colors, to guarantee accurate drawing of the image. Given that 256-color display is almost a standard, at least here on campus, I may not worry too much about what palette is necessary.... Also, I attended WorkForce 2002 at Marquette University. I was able to get five of my resumes out to various companies including Kohler, HK Systems, SBC Ameritech, and Kimberly Clark. I was not able to do any more work today, since we did not return from Milwaukee until Midnight.
 

Friday, February 8:

Met with Dr. Pankratz, and discussed my progress on the project thus far. It seems that he is pleased with my Plan of Attack and my attitude toward this project. He gave me some pointers as to how I should continue my work, and he interrogated me to see how solid my plan of attack was. I am relieved that he is somewhat satisfied with my progress, and that adds fuel to the fire of urgency as I attempt to get the bulk of the development done before spring break...
 

Sunday, February 10:

Researched pixel reading in C++. Internet searches provide a lot of useless junk, mostly pertaining to GL programming, whatever that is. I discovered a method on a "Blitz Basic" message board (what the hell is Blitz Basic, anyway?) that makes use of bitwise operators to convert a single-byte pixel value into 3 RGB values. As Dr. Pankratz had hinted to me, this is the answer to my problem of reading pixels and displaying them with MFC's SetPixel(). Armed with this info, I can once again plunge forward in the design of the CS460 Image Editor...
 

Week 5: February 11 - February 17

Monday, February 11:

Week 5 already? AAAHHHHH! Actually, I am for the most part, on track with this grand adventure. Today I have coded the class BMPImage, and put it in a header file BMPedit.h. The class, as promised contains the data structure for the bitmap, all necessary variables, and a read-from-a-file function at this time. I am still working out compile errors, though, and expect to run it tomorrow....
 

Tuesday, February 12:

Got the thing compiled. However, it does not seem to work the way I want it to. While debugging the program to see if data were properly read, I discovered just the opposite. Enlisting the cheerful assistance of Drs. Pankratz and McVey, it has been determined as of today tha using C++ struct objects to store header data is not going to work; using read() with structs has been demonstrated today to NOT work, while reading in variables separately HAS been successful. Dr. Pankratz also showed me that it is important to actually KNOW what I'm looking for in a Bitmap file. Using DEBUG in DOS, we were able to view and verify the file header contents, and also to verify the size of the objects in the file header(s). There was also some discrepancy between the data types I used from my sample code and what type names meant in Win32.... I suspect that I will have to continue reading variables from the file one at a time....
 

Wednesday, February 13:

I have now fixed my code so that it can read the entire bitmap file into my "data structure". All file and infoheader data had to be contained in separate, independent variables. According to Dr. McVey, this is because reading entire structs can only be successful if the file was created using structs. Since I am working with files from many different sources, it would be impossible to guarantee this, and therefore I must read all variables individually. I have also successfully created a 2-D array using MFC CArray objects. One array is an array of byte variables, which each array representing a single scan line from the bitmap. The whole of the image data is an array of scan line arrays, hence the 2-D array. Tomorrow I will write the data to another file using the "SaveAs" menu call handler function to check if I read the file correctly.
 

Thursday, February 14:

I created the "write" function, which has successfully written the data from one bitmap to another. I tested the function by comparing data values in debugging, and also by opening the two bitmaps simultaneously. Upon my success, however, rests a problem. Until now, I had assumed that using 8-bit pixel bitmaps with 256 color palettes would be sufficient. However, a photo that was a bitmap which I tried to open and rewrite turned out to be 24-bit RGB. This means that each pixel was represented by 3 bytes, 1 each for R,G, and B color values. Upon doing some quick research, I determined that I must switch to using 24-bit RGB format because uncompressed JPEG data is in 24-bit RGB. I will attempt the conversion tomorrow...
 

Friday, February 15:

After some intial setbacks regarding the use of CArray objects, I have successfully read and wrote, without error, a 24-bit RGB bitmap. The structure for the image data consists of a "pixel" class that contains 3 BYTE-sized integers which contain RGB values, an array of pixel class objects (which represents the scan lines), and finally an array of scan lines. This conversion worked to perfection, as evidenced by the simultaneous viewing of the bitmaps in MS Photo Editor. Another reason for the switch to RGB is that the test pics I create with MSPaint will be in 24-bit RGB, so there you go. Next up is drawing the image, which I will try to work on this Saturday and Sunday if time allows.....
 

Saturday/Sunday February 16-17:

Regrettably, no work done this weekend. The combination of long work hours, a band concert, and visitors from home has taken all my time. Back At it on Monday.....
 

Week 6: February 18 - February 25

Monday, February 18:

Today I managed to draw a bitmap image onto the client area of my main window. Only problem is that when the window repaints, the picture disappears. After "asking around" I discovered that I must use the Windows device context CPaintDC, as opposed to CClientDC, and do all drawing in OnPaint(). This function handles all WM_PAINT messages, so when a window must be refreshed, a message is passed to OnPaint(), which then calls my BMPDraw() function. To activate a redraw from my program, I must call AfxGetMainWnd()->Invalidate(TRUE); I must implement this tomorrow.
 

Tuesday, February 19:

Calling my BMPDraw() function ONLY from OnPaint() has proven to be a success. My program also appears to run faster after this change, which is good. I also managed to create two functions that adjust the brightness of the image, one for increasing, and one for decreasing brightness. Brightness is adjusted, in short, by scaling the RGB values for each pixel up or down by a set increment amount. That is, each RGB value is incremented by, say 10, or decremented by 10 for each call of a brightness adjusting function. Limits must also be placed on how high a pixel can be Adjusted, so that no wrapping of integers occurs. I also solved a problem with the scope of my image pointer variable, but it may only be a temporary fix.
 

Wednesday, February 19:

Black-and-White and Negative conversions were written. To convert a color to black and white (gray scale), I discovered that one need only take the average of a pixel's RGB values, and replace each RGB with the averaged result. I came to this conclusion after seeing that any pixel drawn where R, G, and B were equal came out to be shade of gray. It works rather well. Negative images are created by replacing the RGB values with the result of 255-RGB(for each RGB value). My function that turns images negative works to great effect. Also researched info on adjusting contrast. More later. At night: Added checking schemes so that user cannot close without making sure that image can be saved if desired. Also added error checking in BMPRead() so that the File_Open handler breaks if the file is invalid.
 

Thursday, February 20:

Met with Dr. Pankratz to discuss my current situation. Received recommendations for website, and how to go about documentation for the website and for the "mini-presentation" in two weeks. Worked on updating web page, determined what I need to add....
 

Sunday, February 24:

Posted source code to the website. Beginning writing of documentation...
 

Week 7: February 25 - March 3

Monday, February 25:

Completed documentation for both the BMPImage Class and the source code for the windows interface. Began exploring methods for adjusting the contrast of an image.
 

Tuesday, February 26:

Started writing code to adjust the contrast of an image. The general algorithm is to first compute the mean luminance for all of the image's pixels, and then to adjust each RGB value of each pixel up or down depending on its relationship to the mean luminance value. So far, results are marginal, but I am toying with variations on the main theme...
 

Wednesday, February 27:

After some job hunting, I continued to attempt improvements on my contrast adjusting algorithm. The adjusted image is comparable to a contrast adjustment on MS Photo Editor, but not perfect. I have finalized the algorithm and decided to move on for now... At night, I developed a function that causes the image to be redrawn as a mirror of itself.
 

Thursday, February 27:

I added a new feature today, one which adjusts the tint of an image. The user can make an image have a red, green, or blue tint, as well as remove any trace of that color from an image. I also toyed with ideas for writing the Rotate and Magnification/Zoom features. I'm also debating adding a Resize feature, but not sure yet.....
 

Saturday, March 2:

Started coding the Windows dialog box stuff for the Rotate feature, and hit a snag that some Windows gurus on the Net should be able to help me with......
 

Sunday, March 3:

Today I'm working on an outline of topics for this weeks mini-presentation. Will email to DCP for approval....
 

Week 8: March 4 - March 11

Monday, March 4:

Re-evaluated my plans for doing the Rotate function. I have decided not to use a windows dialog box control. I will now merely use only one function that rotates an image 90 degrees. For the user to perform multiple or extended rotations, the user would simply perform 2 or more 90 degree rotates. I have changed my mind on this because I am limiting rotations to 90 degree intervals, and a complex dialog box interface would be overkill in this case. Were I to allow rotation by any degree, the dialog box control would be more practical... Today I also continued to plan my walkthrough materials...
 

Tuesday, March 5:

Performed the walkthrough. I will have to be more organized in my presentation next time, so as to facilitate my public speaking, which is subpar.... On the upside, I impressed the professors with the progress I have made so far, and received a ton of suggestions on how to improve my program. Many of the improvements suggested had to do with the usage of space in my code. It was said, in essence, that my methods of modifying image data were sound, but my usage of data structures to hold altered image data was wasteful and caused the program to run slower than it should. It was suggested that I modify an image by ONLY modifying the pixels on the screen, NOT altering the data in memory then redrawing the whole image. I have no clue as of yet how I can do this and be able to reclaim the data from the screen to save it, but Dr. McVey gave me a great hint with regards to using the Windows "Device Contexts" as areas in which to store and modify image data. Must read more on the subject.....
 

Wednesday, March 5:

I fixed the Mirror function so that it mirrors an image in place, as per Ms. Gibson's suggestion during yesterday's walkthrough. It runs visibly faster than the old version. I also scoured MSDN for detailed info on Windows DC's (device contexts) and how they are used in Windows image processing....
 

Friday, March 7:

I had a revelation today: I know how I can modify pixels directly on the screen. Using the GetPixel() function, I can extract RGB data for each pixel, modify it, and repaint the pixel back onto the DC from which it came. The only problem is whether I can access CMainWindow's CPaintDC from outside functions. If I can do that, then it's simpler than I thought. If not, I will have to use a temporary DC, (class CDC, maybe another CPaintDC) to store modified data and then in OnPaint() copy the data from the temporary DC to CPaintDC. The extra image class object could be eliminated, and loads of processing time would be saved!
 

Saturday, March 8 - Sunday, March 17: SPRING BREAK
 

Monday, March 18 - Sunday, March 24:

During this week I decided to undertake the streamlining of my program. With Dr. McVey's help, I was able to use Windows Device Contexts to edit and redraw images much, much faster. I now have the tricky task of completely adapting the code so that it refreshes properly and also saves properly... I need to devise a way to store an image in a "temporary" DC so that it can be transferred to the window when the client area is invalidated.. My attempts on Saturday met with failure....
 

Week 10: March 25 - March 31

Monday, March 25:

Today met with more frustration regarding creating a new CDC object and drawing an image on it in memory. My program kept asserting, and saying that the DC was NULL. I must be missing a command somewhere along the line...
 

Tuesday, March 26:

More frustration.... Cleaned up my code a little, though... Set up a meeting with Dr. McVey....
 

Wednesday, March 27:

Today, I ran across a JPEG library that is very compatible with the data structures I use in my program... Once I learn how to link this library, I should really be in business as far as JPEGs are concerned. My Meeting with Dr. McVey also went well... We discoveredt the problem lied in part WHERE the new DC was created, and we also missed a call to the CDC constructor... However, there are more minor bugs to work through... For some reason, when part of a dialog box overlaps the image in the window, that part does not reappear when the dialog box closes... That is the most major bug right now....
 

Thursday, March 28:

Met with Dr. Pankratz today, and he told me among other things that I needed to clean up my code... This I was aware of previously, but DCP told me that Dr. McVey had some ideas for me, which will be helpful... I am also glad to learn that my program will be a part of the CS curriculum in the future! My work will help further the education of others!!
 

Week 11: April 1 - April 7

Tuesday, April 2:

Fixed most major bugs in newest version of program. Image now properly refreshes in all cases. The image also saves properly... I achieved this by having the editing functions take their data from the temporary DC in memory as opposed to the PaintDC, since the PaintDC can be considered unreliable, due to the nature of multitasking.. This works like a charm. Got the rotate function to "sort of" work, but unable to fix the bugs tonight....
 

Wednesday, April 3:

Demo'ed the program for Dr. Pankratz today... He played around with it and tried to "break" it to see if something needed to be addressed. Fortunately, there was nothing that happened that I didn't expect to happen... Also talked to Dr. McVey about scrollbar programming, and she told me to just look at my MFC book for some code to use, due to the fact that I got other things to address yet... (ZoomIn, ZoomOut, etc.)
 

Week 12: March Arpil 7 - April 14

Monday, April 8:

Today I talked to Dr. McVey about what needed to be done to my code to "clean it up" and left her hard copies so she can dissect them this week. At night, I got the scrollbar installed, and it works well except for the fact that it's slow as mud!!!! Next I have to work on image magnification...
 

Tuesday, April 9:

Started on the ZoomIn function this evening. Having problems already, and I'm starting to get worried. This was supposed to be easy!!! I'll drop in by McVey tomorrow and have her look at my algorithm....
 

Wednesday, April 10:

McVey gave me advice on what to do about my code... Basically, I have to cut up the program into more files to speed compile time and aid readability. I'll probably end up having .h and .cpp files for the Main Window, the Dialog Boxes, and the BMPImage class. I also had her look at my code, which was really bugging me by that afternoon. We fixed the problems. My algorithm was correct, it was just a matter of where certain statements were placed. I then had a problem with the redraw of a magnified image. The temporary DC where it was stored was not storing the whole image. I solved the problem by moving the image as a whole CBitmap structure to another DC, and giving the temp_dc a clean CBitmap that matched the dimensions of the expanded bitmap. This worked like a charm, but then the Undo algorithm asserted on me, because of some Array-out-of-range error. This means I gotta save the ORIGINAL dimensions of a bitmap and use them when the program reverts to the original version. I'll do that Friday....
 

Friday, April 12:

I fixed the UNDO problem, and managed to code the ZoomOut function correctly on the first try! It all works pretty slick now, except for the Rotate function, but I suspect it may be a similar problem to that of the resizing funcitons (bitmap dimensions in the DC). Will do that tomorrow...
 

Saturday, April 13:

Between shifts at work ("They call me the workin' man....") I got that blasted Rotate function to work properly. Part of the problem was having the dimensions for the temp_dc being wrong, and part of it was how I was moving the pixels. Nonetheless, I got it working, and it works DAMN good! All I have to do now is go through and test everything so that no errors fall through the cracks. I also have to "cut up" my code as per McVey. Then I'll be pretty much done!!!!!
 

Week 13: April 14 - April 21

Monday, April 15:

Today I debugged some things in BMPEdit24.h that needed to be fixed. I managed to get the error checking in BMPRead() to work again but making sure a new image object was created, and all the old data cleared out, if there was an error in the file. BMPRead now returns one of 5 numbers that indicate the status of the file read 0 means OK, -1 signifies an error opening the file, -2 means that the file is not a bitmap, -3 means that the bitmap is not 24-bit RGB, and -4 means that the bitmap is compressed (can't process). It is up to the program or interface that calls BMPRead() to decide how to interpret the return data. I decided that it was not wise to have Windows message boxes being created inside the image editing class, since that will detract from portability. My new method is much more elegant. I also took all the code that is used to find the starting points on a window at which to plot a bitmap and wrapped them into two functions: BMPGetStartX(LONG) and BMPGetStartY(LONG). Cleans up the source code nicely. On Wed. I will begin breaking up the program into more separate files....
 

Wednesday, April 17:

tonight I began breaking up my program so that it is contained in no less than 7 separate files (not counting menu.rc and resource.h). Dr. McVey says that this is good for readability, portability, and speeds compile time. I managed to do it "almost" right the first time, but still have two errors in wingdi.h that seem to have nothing to do with my code. I'll talk to McVey tomorrow, should be no big deal
 

Thursday, April 18:

Dr. McVey said my problem lied in my use of a constant called BITMAP that holds the integer 19778. It is used to check if a file being read is indeed a bitmap.  So, I changed the name of the variable.  After fixing some access-related problems, the program worked again.  The access problems were related to the image object NOT being able to be defined as a global. I had to "get" it from CMainWindow if, say, I needed access to it inside a dialog box.
 

Friday, April 19:

Today marks the last of my tinkering with this program <sniff....>.  Next week shall be devoted entirely to gearing up for the presentation, fixing this blasted website, and polishing up on public speaking skills.  Today I changed the structure of the ScanLineIndex so that it is an array of Windows COLORREF variables, instead of PixelRGB class objects.  This is clearly more efficient storage-wise, since I can extract individual RGB values from COLORREF variables at will. Why would I need to actually store every pixel component in an array? I also changed all the editing functions so that the class PixelRGB is now no longer needed.  I may be hallucinating, but the program may be running visibly faster as a result of the changes!
 

Week 14: April 22- April 28

Monday, April 22:

Tonight I started commenting all of the source code. Got most of it done

Tuesday, April 23:

Continued with the commenting

Wednesday, April 24:

Did last minute testing; all is well. Also wrote the Presentation document and will hand it in to profs tomorrow as planned.

Friday, April 26:

Finsihed commenting code. Got a list of topics to make visual materials about for the Q&A Session....

Saturday, April 27:

Updated all documentation. Cleaned up this website. Loaded all applicable files to the project. Also getting slides and visuals ready, hopefully going to write up my speech tonight, if not, I will practice a little with the equip. in Cofrin, make sure everything works. (No reason why it shouldn't....)

Sunday, April 28:

Continued to prepare materials for presentation.  Wrote out the first 10 minutes.  Practiced the opening monologue and my demonstration sequence twice.

Monday, April 29:

The time is at hand..... I prepared the last of the diagrams to make sure they were acceptable and viewable.  At 5:30, project was presented.  All indications at this time point to a successful defense.  A great load is taken off my back....

Sunday, May 5:

Finalized web page, prepared documents for turning in to DCP.  Placed all source code, user manual, README's, and an .exe version of the program into a .ZIP package for use on the webpage......
 

Monday, May 6:

Turn in all materials relative to the project.  Relax.....