Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Saving a 4-bit BMP in SCREEN 12 (thread314-747791 )

Status
Not open for further replies.

QBO

Programmer
Feb 13, 2013
5
US
thread314-747791

I cut and pasted the code from the above thread, and it worked perfectly. I tried making the area smaller by passing other values for the mins and maxes, and it produced corrupted BMPs. It's been a long time since I programmed in QBASIC, and it's coming back to me, but I can't figure out what is going wrong. I'm trying to make a bitmap from, for instance, (89, 41) to (530, 462). Thanks for listening.
 
Right. I tried passing numbers instead of variables, and I tried making the line lengths divisible by four. The resulting BMP provokes an error in Windows Photo Viewer, and Irfanview displays it as a "torn-looking" version, as if the line scans are out of sync, almost like an old TV with the horizontal hold out of whack. I am guessing that there is something in the code of SAVE4BIT that needs to be changed to accommodate other dimensions. If the problem is at my end, I'm sure I'll see it eventually. It's just that I don't understand the code that builds the BMP as completely as I should, and I'm hoping somebody in here will make me feel like an idiot.
 
You know what? I guess I should mention that it's in DOSBOX.
 
Glad to see you're still with me. I wish to God every day that I had kept my TRS-80, but, no---no old rig (I have a monster gaming rig). I studied the code of SAVE4BIT, and I think I get it now, but I still can't see what's wrong. Evrything lines up as far as I can tell: 14, 40, 64, data to EOF. I intend to take some time this afternoon to modify it into a diagnostic program that will spit out parameters for me to check as it goes, and to try it without the color stuff, since I am in black-and-white.
 
I haven't figured it out yet but it seems to do with the dimensions of the bmp. My guess is that the for..loops in the save4bit sub routine are executing incorrect math (depending on dimensions) and thus write incorrect information to the bmp file.

Windows Viewer (and Paint) show a corrupt file error. However, Paint Shop Pro opens the file but it looks nothing like what it should.

-Geates

 
OK. Thanks. I didn't get a chance to monkey with it yesterday. At least I know now it's not just me. I'll report my findings.
 
It seems as though it's an issue with how the bmp is interpretted. One observation is that the bmp is not corrupt when the width is a factor of 8 (4 bits per pixel x 2 pixels pers Byte). Perhaps the problem is the file header (this looks good, though, compared with Wikipedia []) or how the data is written to the file (this looks good, too).

I modified this code to help me troubleshoot. Here is the modified code:
Code:
DEFINT A-Z
DECLARE SUB SAVE4BIT (FileName$, MinX, MinY, MaxX, MaxY)

TYPE BMPHeader
	ValidID AS STRING * 2
	SizeOfFile AS LONG
	Reserved AS LONG
	OffsetOfBitMap AS LONG
END TYPE

TYPE WindowsBMPInfoHeader
	SizeOfHeader AS LONG
	Widthz AS LONG
	Heightz AS LONG
	Planes AS INTEGER
	BitsPerPixel AS INTEGER
	CompressMethod AS LONG
	ImageSizeInBytes AS LONG
	HorizontalResol AS LONG
	VerticalResol AS LONG
	ColorsUsed AS LONG
	ImportantColors AS LONG
END TYPE

SCREEN 12

FOR Y = 0 TO 49
	LINE (0, Y)-(50, Y), (Y MOD 15)
NEXT Y

x2 = 7
y2 = 7
LOCATE 7, 1: PRINT "Width: "; (x2 + 1), "Height: "; (y2 + 1)
LOCATE 9, 1: PRINT "Use arrow keys to change image size."
LOCATE 10, 1: PRINT "Press the Spacebar to capture as bmp"

SAVE4BIT "4bit.bmp", 0, 0, x2, y2

DO
	A$ = INKEY$
	IF (A$ <> "") THEN
		SELECT CASE (A$)
			CASE CHR$(0) + CHR$(72): y2 = y2 + 1 'Up Arrow
			CASE CHR$(0) + CHR$(80): y2 = y2 - 1 'Down Arrow
			CASE CHR$(0) + CHR$(75): x2 = x2 - 1 'Left Arrow
			CASE CHR$(0) + CHR$(77): x2 = x2 + 1 'Right Arrow
			CASE CHR$(32): SAVE4BIT "4bit.bmp", 0, 0, x2, y2
		END SELECT
		IF (y2 < 0) THEN y2 = 0
		IF (x2 < 0) THEN x2 = 0
		LOCATE 7, 1: PRINT "Width: "; (x2 + 1), "Height: "; (y2 + 1)
	END IF
LOOP WHILE A$ <> CHR$(27)
[/highlight]

SUB SAVE4BIT (FileName$, MinX, MinY, MaxX, MaxY)
	DIM BMPHeader AS BMPHeader
	DIM WindowsBMPInfoHeader AS WindowsBMPInfoHeader

	OPEN FileName$ FOR BINARY AS #255
	IF LOF(255) <> 0 THEN
		CLOSE #255
		KILL FileName$
		OPEN FileName$ FOR BINARY AS #255
	END IF
	
	ImageWidth = (MaxX - MinX) + 1: ImageHeight = (MaxY - MinY) + 1
	WindowsBMPInfoHeader.SizeOfHeader = 40
	WindowsBMPInfoHeader.Widthz = ImageWidth
	WindowsBMPInfoHeader.Heightz = ImageHeight
	WindowsBMPInfoHeader.Planes = 1
	WindowsBMPInfoHeader.BitsPerPixel = 4
	WindowsBMPInfoHeader.CompressMethod = 0
	WindowsBMPInfoHeader.ColorsUsed = 16
	WindowsBMPInfoHeader.ImportantColors = 16
	PUT #255, 15, WindowsBMPInfoHeader
	Empty$ = SPACE$(1)
  
	FOR Colors = 0 TO 15
		OUT &H3C6, &HFF
		OUT &H3C7, Colors
		Red$ = CHR$(INP(&H3C9) * 4): Green$ = CHR$(INP(&H3C9) * 4)
		Blue$ = CHR$(INP(&H3C9) * 4): AllColorz$ = Blue$ + Green$ + Red$ + Empty$
		PUT #255, , AllColorz$
	NEXT Colors

	Padding$ = SPACE$(0)
	IF (4 - ((BMPInfoHeader.Widthz MOD 8) / 2)) <> 4 THEN
		Padding$ = SPACE$((4 - ((BMPInfoHeader.Widthz MOD 8) / 2)))
	END IF

	FOR Loops = MaxY TO MinY STEP -1
		FOR Lips = MinX TO MaxX STEP 2
			Byte = POINT(Lips, Loops) * 16
		  
			IF (Lips + 1 <= MaxX) THEN
				Byte = (Byte OR POINT(Lips + 1, Loops))
			END IF
																																									
			Bytez$ = Bytez$ + CHR$(Byte)
			Byte = 0
		NEXT Lips
		PUT #255, , Bytez$
		PUT #255, , Padding$
		Bytez$ = ""
		
	NEXT Loops
	BMPHeader.ValidID = "BM"
	BMPHeader.SizeOfFile = LOF(255)
	BMPHeader.OffsetOfBitMap = 118
	PUT #255, 1, BMPHeader
	CLOSE #255
END SUB

I have the .bmp open in Windows Photo Viewer and it updates the image as you modify it.

-Geates

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top