Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site
Search in forums












SourceForge.net Logo
Home » Developing U++ » UppHub » Raster Control
Raster Control [message #14940] Thu, 20 March 2008 21:58 Go to next message
mdelfede is currently offline  mdelfede
Messages: 1307
Registered: September 2007
Ultimate Contributor
I've created an optimized raster control, usable to view any kind of raster image.
Capabilities :
- Middle mouse button press -- image PAN
- Mouse Wheel               -- scroll up/down
- Shift + mouse Wheel       -- zoom in/out
- Multi paage raster view with optional thumbnails
- quite fast zoom/pans operations even for big images


The control has been developed mainly a viewer for a fax application, but can be useful to other purposes.
Having optimized ring-buffer scrolling, it's not suited to build an image editor; replacing ImageCache stuff with a trimmed version without ring-buffer can make suitable also for editing.

Code is in Bazaar svn repository, starting from SVN 190.

Here a screenshot :

index.php?t=getfile&id=1091&private=0

Ciao

Max
Re: Raster Control [message #15106 is a reply to message #14940] Tue, 01 April 2008 11:22 Go to previous messageGo to next message
mrjt is currently offline  mrjt
Messages: 705
Registered: March 2007
Location: London
Contributor
I've just run RasterCtrlTest and got the following compilation errors (very easy to fix obviously):
c:\uppsvn\bazaar\rasterctrl\rasterctrl.cpp(79) : error C4716: 'RasterCtrl::Open' : must return a value
c:\uppsvn\bazaar\rasterctrl\rasterctrl.cpp(110) : error C4716: 'RasterCtrl::ShowThumbnails' : must return a value


It also seems to crash when loading a single image smaller than the window, as Layout gets called before imageScale is set (I believe).
Re: Raster Control [message #15110 is a reply to message #15106] Tue, 01 April 2008 14:09 Go to previous messageGo to next message
mdelfede is currently offline  mdelfede
Messages: 1307
Registered: September 2007
Ultimate Contributor
mrjt wrote on Tue, 01 April 2008 11:22

I've just run RasterCtrlTest and got the following compilation errors (very easy to fix obviously):
c:\uppsvn\bazaar\rasterctrl\rasterctrl.cpp(79) : error C4716: 'RasterCtrl::Open' : must return a value
c:\uppsvn\bazaar\rasterctrl\rasterctrl.cpp(110) : error C4716: 'RasterCtrl::ShowThumbnails' : must return a value




yes, sorry... the error checking was not finished... I'll update svn today.
BTW, I guess we should enable strict warnings on GCC... mine didn't notice the error.

Quote:


It also seems to crash when loading a single image smaller than the window, as Layout gets called before imageScale is set (I believe).


mhhh... I can't reproduce that. Can you tell me how to do it ? I tested with small icons and all seems ok.

Max

[Updated on: Tue, 01 April 2008 14:10]

Report message to a moderator

Re: Raster Control [message #15111 is a reply to message #15110] Tue, 01 April 2008 15:11 Go to previous messageGo to next message
mrjt is currently offline  mrjt
Messages: 705
Registered: March 2007
Location: London
Contributor
I'm opening an image that doesn't require thumbnails to be shown and is smaller than the window. This causes 3/4 divide by ZERO errors for various reasons. I appreciate that this is kind of the opposite to how the control is supposed to be used though.

- In RasterThumbsCtrl::CalcScale:
int RasterThumbsCtrl::CalcScale(int imScale, int rasterWidth, int maxPageHeight)
{
	// calculates scale factor based on max thumb width
	// slightly smaller than ctrl width
	int maxScaledWidth = iscale(GetSize().cx, THUMBS_HSIZE_MUL, THUMBS_HSIZE_DIV);
	return iscale(maxScaledWidth, 1000, rasterWidth);

} // END RasterThumbsCtrl::CalcScale()
With no thumbnails GetSize().cx is 0 since you have previously set the splitter pos to 0. imageScale is then set to 0 and causes a DIVIDE_BY_ZERO. Adding the following after the call to CalcSize in RasterBaseCtrl::Layout
	if (!imageScale) {
		inside = false;
		return;
	}
fixes it.

- Also RasterBaseCtrl::Layout. You need !0 checks for vScollMax and hScrollMax on the two lines that do:
hScrollBar.Set(iscale(hScrollPos, scaledRasterWidth, hScrollMax));
and the vertical equivalent. I don't really understand what's going on here, but I can't see how this could ever work since vScrollMax should always start as 0. Confused

- RasterBaseCtrl::PaintCache. Add a check for imageScale == 0 at the start of the function.

- ImageCache::Fill, caused when you resize the window down to nothing. Change first line to:
	if(imageBuffer.IsEmpty() || !imageBuffer.GetSize().cx || !imageBuffer.GetSize().cy)


Then everything works very nicely Smile.

You also may want to investigate Upp::Scroller. Not sure if this'll help in your case but it's worth a look.

James

[Updated on: Tue, 01 April 2008 18:12]

Report message to a moderator

Re: Raster Control [message #15112 is a reply to message #15111] Tue, 01 April 2008 15:38 Go to previous messageGo to next message
mdelfede is currently offline  mdelfede
Messages: 1307
Registered: September 2007
Ultimate Contributor
Ok, thanx for suggestions !
I didn't notice the divide by 0 errors... maybe I've got them but didn't make troubles on running demo.

About scrolling, my control repaints inside cache ONLY the scrolled in part of image, that's the speed up stuff.
BUT, it repaints the whole cache on ctrl on Paint() routine.... I don't know if it's worth the effort to repaint only neede areas... For my use, the control is fast enough, and IMO checking to see what needs to be repaint from cache to ctrl is a quite big work.

I'll correct bugs later this nigh on svn. Thanx again for signaling them!

BTW.... what's your use for my control ? or was it just for testing ?

Ciao

Max
Re: Raster Control [message #15115 is a reply to message #15112] Tue, 01 April 2008 16:13 Go to previous messageGo to next message
mrjt is currently offline  mrjt
Messages: 705
Registered: March 2007
Location: London
Contributor
I was just curious. It a very nice control though Smile
Re: Raster Control [message #15123 is a reply to message #15115] Tue, 01 April 2008 18:52 Go to previous messageGo to next message
mdelfede is currently offline  mdelfede
Messages: 1307
Registered: September 2007
Ultimate Contributor
I still don't get divide by 0 errors.... I've tested with many small images, icons and so on, but nothing.
How can you reproduce the problem ?

Max
Re: Raster Control [message #15124 is a reply to message #15123] Tue, 01 April 2008 19:08 Go to previous messageGo to next message
mrjt is currently offline  mrjt
Messages: 705
Registered: March 2007
Location: London
Contributor
Interesting. If you compile with MingW, and presumably GCC as well, you don't get the error. If you look at iscale:
int iscale(int x, int y, int z)
{
#ifdef __NOASSEMBLY__
	return int(x * (double)y / z);
#else
	__asm
	{
		mov		eax, [x]
		imul	[y]
		idiv	[z]
	}
#endif
}

When using MingW __NOASSEMBLY__ is defined, with MSVC it's not. And only the assembler crashes, even though there is still a clear divide by 0. This really should be fixed.
Re: Raster Control [message #15125 is a reply to message #15124] Tue, 01 April 2008 21:05 Go to previous messageGo to next message
mdelfede is currently offline  mdelfede
Messages: 1307
Registered: September 2007
Ultimate Contributor
mrjt wrote on Tue, 01 April 2008 19:08


When using MingW __NOASSEMBLY__ is defined, with MSVC it's not....



Quite interesting stuff, yes... I think fp math can cope with 0/0 problem, using NANs, maybe.
Well, how can I tell GCC to undefine _NOASSEMBLY_ without patching upp code ?

Max

EDIT : well, I've seen why NOASSEMBLY is defined for GCC... asm syntax is different from MSC to GCC.
IMHO the best way would be to do some alternate assembly code instead of dropping it in GCC....
For example, along with NOASSEMBLY we should define a GCC_ASSEMBLY and MSC_ASSEMBLY and react in consequence.
For now I'll make a small patch on my 'mathutils.cpp' stuff...

Max

[Updated on: Tue, 01 April 2008 21:21]

Report message to a moderator

Re: Raster Control [message #15126 is a reply to message #15124] Tue, 01 April 2008 21:57 Go to previous messageGo to next message
mr_ped is currently offline  mr_ped
Messages: 825
Registered: November 2005
Location: Czech Republic - Praha
Experienced Contributor
Not only it is divided into C/ASM, but both code paths are different.

The ASM version works purely with integers, while the C version with (double) will lead to decimal division at least, if not multiply (I'm not that big C guru to fully understand how that casting to double will propagate to the rest of calculations).

To get maybe identical version in C you may try:
return ((x * y) / z);

I'm not sure it will compile absolutely identically, but I think the chances are very good... feel free to compile into ASM firstly and check the result of GCC ASM (-S command line switch?).
Re: Raster Control [message #15127 is a reply to message #15126] Tue, 01 April 2008 22:14 Go to previous messageGo to next message
mdelfede is currently offline  mdelfede
Messages: 1307
Registered: September 2007
Ultimate Contributor
mr_ped wrote on Tue, 01 April 2008 21:57

Not only it is divided into C/ASM, but both code paths are different.

The ASM version works purely with integers, while the C version with (double) will lead to decimal division at least, if not multiply (I'm not that big C guru to fully understand how that casting to double will propagate to the rest of calculations).

To get maybe identical version in C you may try:
return ((x * y) / z);

I'm not sure it will compile absolutely identically, but I think the chances are very good... feel free to compile into ASM firstly and check the result of GCC ASM (-S command line switch?).


Well, maybe will be the same, maybe not.
The problem solved by Iscale is rounding working with integers.
To have no precision loss, you should have a temporary integer with twice the integer width, whichever it is... OR use some MULDIV advanced algorithm.
Because of that some assembly language has a built-in muldiv instruction.
The big problem is that in C you've no guarantee of integer sizes, you just know that :
char <= short <= int <= longint <= longlongint
so, you can't know what size to use in intermediate calculation.... because of that in Iscale they use double.
In GCC32 you should have int(32), long(32) and long long(64), so using longlong would be ok.... but I guess that in GCC64 the int is 64 byte wide (maybe), so it won't work either.
BTW, nor the asm code will work without some cheks.

IMHO, the right approach would be to typedef some integer sizes in Core.h :
typedef char int8
typedef short int16
typedef int int32
typedef longlong int64

depending on machine, then use
int32 Iscale(int32 a, int32 b, int32 c)

so it's compiler sake to give needed warnings.

Max

typedef
Re: Raster Control [message #15128 is a reply to message #15127] Tue, 01 April 2008 22:59 Go to previous messageGo to next message
mdelfede is currently offline  mdelfede
Messages: 1307
Registered: September 2007
Ultimate Contributor
Well, corrected in SVN, now it should work ok on MSC too.

BTW, in the meantime, I've made a patched and (IMHO) better version of Iscale functions, I'll post them in another thread.

Ciao

Max
Re: Raster Control [message #15198 is a reply to message #14940] Tue, 08 April 2008 17:34 Go to previous messageGo to next message
mr_ped is currently offline  mr_ped
Messages: 825
Registered: November 2005
Location: Czech Republic - Praha
Experienced Contributor
I'm trying it from 2008.1beta2 installation, and I hit crash right after opening first image I found on my disc. Smile

It turned out the very first image I found was gif, and you didn't add plugin/gif package, so the RasterCtrl\RasterCtrl.cpp:55 line
raster = StreamRaster::OpenAny(imageStream);

ends with NULL assigned to raster.

Than the next for loop
	for(curPage = 0; curPage < raster->GetPageCount(); curPage++)

will crash due to referencing null pointer.

I think there should be some error handler instead of crash in case the input stream did not result into valid raster object.

Another funny thing I encountered was opening that gif finally (after I did add plugin/gif package), it fits the width of window (it's scaled up a bit) with vertical scrollbar, than I used View / Zoom 10%, than View / Page width, and I do get both vertical and horizontal scrollbars suddenly. After using View / Page width second time, the horizontal scrollbars is gone and I have the "default" view just like after opening the image.
Re: Raster Control [message #15204 is a reply to message #15198] Wed, 09 April 2008 10:28 Go to previous messageGo to next message
mdelfede is currently offline  mdelfede
Messages: 1307
Registered: September 2007
Ultimate Contributor
mr_ped wrote on Tue, 08 April 2008 17:34

I'm trying it from 2008.1beta2 installation, and I hit crash right after opening first image I found on my disc. Smile


well, 2008.1beta2 has an outdated version, anyways... bugs pointed out by mrjt (which caused crash on MSC) are corrected in svn. Please try it, just pick Bazaar from svn, if you don't like to work with upp-svn package.
BTW I stopped upgrading svn packages for the moment cause some lettercase mismatches in uvs2 that brings some problems in linux.

Quote:


It turned out the very first image I found was gif, and you didn't add plugin/gif package, so the RasterCtrl\RasterCtrl.cpp:55 line
raster = StreamRaster::OpenAny(imageStream);

ends with NULL assigned to raster.

Than the next for loop
	for(curPage = 0; curPage < raster->GetPageCount(); curPage++)

will crash due to referencing null pointer.

I think there should be some error handler instead of crash in case the input stream did not result into valid raster object.


I agree with you, the package isn't yet refined, in particular to error handling. I'll add some error checks soon.... sorry for the inconvenience but I made the package for a particular need, not yet with production quality in mind Smile
About the gif plugin, I'm not sure if I should add it to RasterControl package or leave it to users if they need it... But that apply to tiff too. IMHO would be better to leave grafic formats out of rastercontrol package and let users include just what they need.

Quote:


Another funny thing I encountered was opening that gif finally (after I did add plugin/gif package), it fits the width of window (it's scaled up a bit) with vertical scrollbar, than I used View / Zoom 10%, than View / Page width, and I do get both vertical and horizontal scrollbars suddenly. After using View / Page width second time, the horizontal scrollbars is gone and I have the "default" view just like after opening the image.


uh ? I didn't notice that behaviour.... it should hide scrollbars when not needed. A known problem is that it can loose the space used by scrollbars (it makes it necessary to calculate the sizes both for control with and without scrollbars to solve it, it's planned but I'm looking for a good (and quick) solution.
But scrollbars hiding should work... can you post a sample image ?

Finally, I'm now working to the hard(ware) part of my fax application, the modem/serial port/threads stuffs, which is quite complicated. When it'll ok, I'll join together with RasterControl so I'll test it much more in depth....

Max
Re: Raster Control [message #15206 is a reply to message #14940] Wed, 09 April 2008 10:59 Go to previous message
mr_ped is currently offline  mr_ped
Messages: 825
Registered: November 2005
Location: Czech Republic - Praha
Experienced Contributor
Here's the image I was testing with.
(a wallpaper, so I believe the copyright owner will not mind this post Smile )
  • Attachment: pvp37.gif
    (Size: 90.55KB, Downloaded 333 times)
Previous Topic: Job opportunity for Ultimate++ developer
Next Topic: Service/daemon for Ultimate++
Goto Forum:
  


Current Time: Fri Mar 29 12:06:11 CET 2024

Total time taken to generate the page: 0.01118 seconds