Can't Create Image Bug?

Discuss using and improving Lua and the Lua Player specific to the PSP.

Moderators: Shine, Insert_witty_name

Post Reply
alinear
Posts: 5
Joined: Tue Sep 06, 2005 2:27 pm
Location: Brooklyn, NY, USA
Contact:

Can't Create Image Bug?

Post by alinear »

Hello, when I run the following code in PC lua player alpha it runs reasonably, but when I run it on PSP luaplayer it quite often encounters the error:

error: script.lua:61: can't create image

Here is the script...

Code: Select all

-- USB DISK MODE ACTIVATED FOR DEVELOPMENT
System.usbDiskModeActivate();

-- CLEAR THE SCREEN ON INIT
screen:clear();

-- GENERATE SCREEN BUFFER IMAGE
sBuffer = Image.createEmpty(480, 272);

-- GAP SPACING PARAMS
function init()

	--sBuffer:clear();

	rSeed = math.random(1, 100);
	
	if rSeed < 50 then
		gapW = math.random&#40;1, 480&#41;;
		gapH = math.random&#40;1, 10&#41;;
	else
		gapW = math.random&#40;1, 10&#41;;
		gapH = math.random&#40;1, 272&#41;;
	end;
	
	bW = math.floor&#40;480 / gapW&#41;;
	bH = math.floor&#40;272 / gapH&#41;;
	colorRange = 255 / bW;
	max = bW * bH;

	plots = &#123;&#125;;
	p = 0;
	offsetX = 0;
	offsetY = 0;
	
end;

-- CALL INIT
init&#40;&#41;;

-- MAIN LOOP
while true do

	if p < max then
	
		for p = p, p + bW do
		
			stretch = 272 - offsetY;
			
			if stretch < 1 then stretch = 1; end;
			if stretch > 255 then stretch = 255; end; -- !!! WEIRD OPTIMIZATION, > 255 CHOKES UP !!!
			
			colorMax = &#40;p + 1&#41; * colorRange;
			
			rr = math.random&#40;0, colorMax&#41;;
			rg = math.random&#40;0, colorMax&#41;;
			rb = math.random&#40;0, colorMax&#41;;
			
			--plots&#91;p&#93; = Image.createEmpty&#40;1, stretch&#41;;
			--plots&#91;p&#93;&#58;fillRect&#40;0, 0, 1, stretch, Color.new&#40;rr, rg, rb&#41;&#41;;
		
			plots&#91;p&#93; = Image.createEmpty&#40;gapW, stretch&#41;;
			plots&#91;p&#93;&#58;fillRect&#40;0, 0, gapW, stretch, Color.new&#40;rr, rg, rb&#41;&#41;;
			--plots&#91;p&#93;&#58;clear&#40;Color.new&#40;rr, rg, rb&#41;&#41;;
		
			sBuffer&#58;blit&#40;offsetX, offsetY, plots&#91;p&#93;&#41;;
			
			offsetX = offsetX + gapW;
			
			if offsetX > 480 then
				offsetX = 0;
				offsetY = offsetY + gapH;
			end;
		
		end;
		
	end;

	screen&#58;blit&#40;0, 0, sBuffer, 0, 0, 480, 272, false&#41;;

	screen.waitVblankStart&#40;&#41;;
	screen.flip&#40;&#41;;
	
	-- READ CONTROLS TO OBJECT 'INPUT'
	input = Controls.read&#40;&#41;;
	
	-- PAD MOVEMENT RE-INITS
	if input&#58;up&#40;&#41; then init&#40;&#41;; end;
	if input&#58;down&#40;&#41; then init&#40;&#41;; end;
	if input&#58;left&#40;&#41; then init&#40;&#41;; end;
	if input&#58;right&#40;&#41; then init&#40;&#41;; end;
	
	-- TERMINATE ON START BUTTON
	if input&#58;start&#40;&#41; then
		break;
	end;
	
	-- SAVE SCREENSHOT ON SELECT BUTTON
	if input&#58;select&#40;&#41; then
		Image&#58;save&#40;"screen_noise.png"&#41;;
	end;
	
end;
and here is line 61...

Code: Select all

			plots&#91;p&#93; = Image.createEmpty&#40;gapW, stretch&#41;;
Is there some kind of issue with generating a large number of dynamic images in this manner... and if so is there a better way to do this in lua?

Also noticed a funny glitch on the PC lua player... if you alternate these lines (alternate which one is commented out):

Code: Select all

			plots&#91;p&#93;&#58;fillRect&#40;0, 0, gapW, stretch, Color.new&#40;rr, rg, rb&#41;&#41;;
			--plots&#91;p&#93;&#58;clear&#40;Color.new&#40;rr, rg, rb&#41;&#41;;
Presumably, visually, both lines should sorta 'do' the same thing. But on PC lua player the fill method looks proper, whereas the clear method gets a very unusual color value and appears to have mucked up alpha values (looks like the color assignment has actually somehow bitshifted rrggbb to something like *rggbba* or something screwy like that...).

Any insight is appreciated.
alinear
Posts: 5
Joined: Tue Sep 06, 2005 2:27 pm
Location: Brooklyn, NY, USA
Contact:

Post by alinear »

I removed the incremental image name handles, they were a holdover from some other experimenting I was doing... since the pass render is being blitted to a sort of snapshot buffer I didn't need to inc. the image name -- just stamp each pass and move on:

Code: Select all

         plot = Image.createEmpty&#40;gapW, stretch&#41;;
         plot&#58;fillRect&#40;0, 0, gapW, stretch, Color.new&#40;rr, rg, rb&#41;&#41;;
         --plot&#58;clear&#40;Color.new&#40;rr, rg, rb&#41;&#41;;
      
         sBuffer&#58;blit&#40;offsetX, offsetY, plot&#41;;
BUT even with this change I still get the same line 61 can't create image error...

Still scratching my head...
Shine
Posts: 728
Joined: Fri Dec 03, 2004 12:10 pm
Location: Germany

Post by Shine »

I don't understand your code, looks like it allocates new images forever and stores it in the array at position 0 and 1. This should be no problem, because the old image would be GC'ed, but there is a bug in version 0.9 of Lua Player, add "collectgarbage()" in your loop.
alinear
Posts: 5
Joined: Tue Sep 06, 2005 2:27 pm
Location: Brooklyn, NY, USA
Contact:

Post by alinear »

Here is the final code with a lot of comments

Code: Select all

-- USB DISK MODE ACTIVATED FOR DEVELOPMENT
System.usbDiskModeActivate&#40;&#41;;

-- CLEAR THE SCREEN ON START
screen&#58;clear&#40;&#41;;

-- GENERATE SECONDARY SCREEN BUFFER IMAGE
sBuffer = Image.createEmpty&#40;480, 272&#41;;

-- INIT FUNCTION, ESTABLISHES PATTERN PROPERTIES
function init&#40;&#41;

	-- CLEAR OLD IMAGE BUFFERS
	sBuffer&#58;clear&#40;&#41;;
	screen&#58;clear&#40;&#41;;
	
	-- FORCE GARBAGE COLLECTION
	collectgarbage&#40;&#41;;

	-- BRANCH TO SEMI RANDOMLY DECIDE IF PATTERN IS WIDER OR TALLER
	-- DEFINES PATTERN GRID GAP SIZES
	rSeed = math.random&#40;1, 100&#41;;
	
	-- GREATER CHANCE OF WIDER LINES VS TALLER LINES
	if rSeed < 75 then
		gapW = math.random&#40;10, 480&#41;;
		gapH = math.random&#40;1, 10&#41;;
	else
		gapW = math.random&#40;1, 10&#41;;
		gapH = math.random&#40;10, 272&#41;;
	end;
	
	-- CALC RATIOS OF SCREEN TO GRID GAP SIZES
	bW = math.floor&#40;480 / gapW&#41;;
	bH = math.floor&#40;272 / gapH&#41;;
	
	-- COLOR RANGE SCALAR
	colorRange = 255 / bW;
	
	-- DETERMINE MAX NUMBER OF ITERATIONS NEEDED TO FILL SCREEN
	max = bW * bH;

	-- INIT VARS
	p = 0;
	offsetX = 0;
	offsetY = 0;
	
end;

-- CALL INIT
init&#40;&#41;;

-- MAIN LOOP
while true do

	-- LOOP THROUGH ALL ITERATIONS
	if p < max then
	
		-- ITERATE BY FULL ROWS
		for p = p, p + bW do
		
			-- DETERMINE REMAINING HEIGHT IN CANVAS FROM CURRENT ITERATION
			stretch = 272 - offsetY;
			
			-- LIMIT V STRETCH RANGES
			if stretch < 1 then stretch = 1; end;
			-- if stretch > 255 then stretch = 255; end; -- !!! LUAPLAYER WIN OPTIMIZATION !!!
			
			-- DEFINE RANGE OF RANDOMNESS OF COLOR BASED ON COLUMN ITERATION
			colorMax = &#40;p + 1&#41; * colorRange;
			
			-- GENERATE RANDOM R G B VALUES
			rr = math.random&#40;0, colorMax&#41;;
			rg = math.random&#40;0, colorMax&#41;;
			rb = math.random&#40;0, colorMax&#41;;
			
			-- DRAW AN IMAGE TO PLOT THE CURRENT ITERATION
			plot = Image.createEmpty&#40;gapW, stretch&#41;;
			
			-- SWAPPING THESE FILL METHODS SEEMS TO PRODUCE DIFFERENT VISUAL RESULTS
			-- IN LUAPLAYER/WIN, PRODUCE SAME VISUAL RESULTS IN LUAPLAYER/PSP
			-- plot&#58;fillRect&#40;0, 0, gapW, stretch, Color.new&#40;rr, rg, rb&#41;&#41;;
			plot&#58;clear&#40;Color.new&#40;rr, rg, rb&#41;&#41;;
		
			-- STAMP THE ITERATION TO THE SECONDARY SCREEN BUFFER
			sBuffer&#58;blit&#40;offsetX, offsetY, plot&#41;;

			-- FORCE GARBAGE COLLECTION
			collectgarbage&#40;&#41;;
			
			-- INC THE COLUMN POSITION &#40;H&#41;
			offsetX = offsetX + gapW;
			
			-- LOOP THE COLUMN POSITION, INC THE ROW POSITION &#40;V&#41;
			if offsetX > 480 then
				offsetX = 0;
				offsetY = offsetY + gapH;
			end;
		
		end;
		
	end;
	-- ^^ END ITERATIONS &#40;UNTIL RE-INITIALIZED&#41;
	
	-- BLIT THE SECONDARY SCREEN BUFFER TO THE STANDARD OFF-SCREEN BUFFER
	screen&#58;blit&#40;0, 0, sBuffer, 0, 0, 480, 272, false&#41;;

	-- WAIT FOR VBLANK SYNC
	screen.waitVblankStart&#40;&#41;;
	
	-- FLIP OFF-SCREEN BUFFER TO VISIBLE SCREEN
	screen.flip&#40;&#41;;
	
	-- READ CONTROLS TO OBJECT 'INPUT'
	input = Controls.read&#40;&#41;;
	
	-- PAD MOVEMENT RE-INITS
	if input&#58;up&#40;&#41; then init&#40;&#41;; end;
	if input&#58;down&#40;&#41; then init&#40;&#41;; end;
	if input&#58;left&#40;&#41; then init&#40;&#41;; end;
	if input&#58;right&#40;&#41; then init&#40;&#41;; end;
	
	-- TERMINATE ON START BUTTON
	if input&#58;start&#40;&#41; then
		break;
	end;
	
	-- SAVE SCREENSHOT ON SELECT BUTTON
	if input&#58;select&#40;&#41; then
		Image&#58;save&#40;"screen_noise.png"&#41;;
	end;
	
end;
The forced garbage collection appears to have gotten rid of the image allocation problem... also, as I posted above I got rid of it using an array to allocate the image iterations in favor of just using a single image that gets reinit each pass...

I just made this little noise/pattern generation thing, mainly to understand how to manipulate blits and mess with lua, and to stress luaplayer a bit to see how it performs...

What I've found is...

- Seems to obviously perform a lot better drawing horizontal lines (across rasterlines) vs. vertical (against rasterlines).

- Has an unusual behavior in luaplayer pc where if you, for example, are drawing solid boxes dynamically and you decide to just create an image of your boxes x/y size then clear it with a color to fill it, vs. if you create the image then draw a rectangle in it... the performance visually looks about the same, visually looks the same on PSP luaplayer, but on PC (win) luaplayer the 2 different methods produce visually different results... The 'clear' method looks like it screws up the clear fill color, transposing the color values and even affecting the alpha (t/f) even when it is undefined...

Code: Select all

			-- SWAPPING THESE FILL METHODS SEEMS TO PRODUCE DIFFERENT VISUAL RESULTS
			-- IN LUAPLAYER/WIN, PRODUCE SAME VISUAL RESULTS IN LUAPLAYER/PSP
			-- plot&#58;fillRect&#40;0, 0, gapW, stretch, Color.new&#40;rr, rg, rb&#41;&#41;;
			plot&#58;clear&#40;Color.new&#40;rr, rg, rb&#41;&#41;;
- On PSP luaplayer when you draw vert lines (boxes, fills) the performance is generally slow unless the lines are not very many rasterlines tall (a bit less than 100 pixels). On PC luaplayer, when you draw vert lines (boxes, fills) the performance is great up until it reaches 255 pixels high, then it suddenly gets very slow (very big diff. between iterating >= 255 pixels high vs. < 255 pixels high).

Thanks for pointing out the garbage collection thing!
Post Reply