@@ -301,6 +301,132 @@ procedure UnGzip(Data: TStream; Result: TStream); //gzdecode from PHP
301301 end ;
302302end ;
303303
304+
305+ function LBM_Read (Bmp: TPV_Bitmap; Str: TStream): Boolean;
306+ var Reader: TPV_Reader;
307+ Reader2: TPV_Reader;
308+ Width, Height: Integer;
309+ R,G,B,A: Byte;
310+ x,y: Integer;
311+ i,k,j: Integer;
312+ form, ilbm: String;
313+ size: Cardinal;
314+ bmWidth, bmHeight, bmX, bmY, bmPlanesCount, bmMasking, bmCompression,
315+ bmPad1, bmTransColor, bmXAspect, bmYAspect, bmPageWidth, bmPageHeight: Cardinal;
316+ chName: String;
317+ chSize: Integer;
318+ col: Byte;
319+ pal: array [0 ..255 ] of TPix;
320+ rr: array of Cardinal;
321+ gg: Byte;
322+ p: TPix;
323+ Mem: TMemoryStream;
324+ begin
325+ Reader := TPV_Reader.Create(Str);
326+
327+ form := Reader.getS(4 );
328+ size := Reader.getMU4;
329+ ilbm := Reader.getS(4 );
330+
331+ if form <> ' FORM' then begin
332+ Reader.Free;
333+ Exit(False);
334+ end ;
335+
336+ if (ilbm <> ' ILBM' ) and (ilbm <> ' PBM ' ) then begin
337+ Reader.Free;
338+ Exit(False);
339+ end ;
340+
341+ while Reader.Offset < Reader.Size do begin
342+ chName := Reader.getS(4 ); // LBM Chunk
343+ chSize := Reader.getMU4;
344+
345+ if chName = ' BMHD' then begin
346+ bmWidth := Reader.getMU2;
347+ bmHeight := Reader.getMU2;
348+ bmX := Reader.getMU2;
349+ bmY := Reader.getMU2;
350+ bmPlanesCount := Reader.getU;
351+ bmMasking := Reader.getU;
352+ bmCompression := Reader.getU;
353+ bmPad1 := Reader.getU;
354+ bmTransColor := Reader.getMU2;
355+ bmXAspect := Reader.getU;
356+ bmYAspect := Reader.getU;
357+ bmPageWidth := Reader.getMU2;
358+ bmPageHeight := Reader.getMU2;
359+
360+ Bmp.SetSize(bmWidth, bmHeight);
361+ end
362+ else if chName = ' CMAP' then begin // palette
363+ for i:=0 to ceil(chSize/3 )-1 do begin
364+
365+ pal[i].r := Reader.getU;
366+ pal[i].g := Reader.getU;
367+ pal[i].b := Reader.getU;
368+ end ;
369+ end
370+ else if chName = ' BODY' then begin // image body
371+
372+ Mem := TMemoryStream.Create;
373+ Str.Position := Reader.Offset;
374+
375+ setLength(rr, bmWidth);
376+
377+ if bmCompression = 1 then begin // RLE
378+ Unrle_LBM(Str, Mem, Str.Size-Str.Position);
379+ Mem.Position := 0 ;
380+ Reader2 := TPV_Reader.Create(Mem);
381+ Reader.Offset := Str.Size;
382+ end
383+ else begin
384+ Reader2 := TPV_Reader.Create(Str, chSize);
385+ Reader.Offset := Reader.Offset + chSize;
386+ end ;
387+
388+ for y:=0 to bmHeight-1 do begin
389+ for i:=0 to bmWidth-1 do rr[i] := 0 ;
390+
391+ // showmessage(IntToStr(bmPlanesCount));
392+
393+ for k:=0 to bmPlanesCount-1 do // for every bitplane
394+ for x:=0 to ceil(bmWidth/8 )-1 do begin
395+ b := Reader2.getU;
396+ for j:=0 to 8 -1 do begin
397+ gg := getBits(b, (8 -1 )-j, 1 );
398+ rr[8 *x + j] := rr[8 *x + j] + (gg shl k);
399+ end
400+ end ;
401+
402+ if bmPlanesCount<9 then
403+ for x:=0 to bmWidth-1 do begin
404+ gg := rr[x];
405+ Bmp.SetRGBA(x, y, pal[gg].r, pal[gg].g, pal[gg].b, 255 );
406+ end
407+ else
408+ for x:=0 to bmWidth-1 do begin
409+ P.RGBA := rr[x];
410+ Bmp.SetRGBA(x,y, p.B, p.G, p.R, 255 );
411+ end ;
412+ end ;
413+
414+ Mem.Free;
415+ Reader2.free;
416+
417+
418+ // break; //TODO: remove
419+
420+ end // Other block- ignore
421+ else begin
422+ Reader.offset := Reader.offset + chSize;
423+ end
424+ end ;
425+
426+ Result := True;
427+ Reader.Free;
428+ end ;
429+
304430function A4MI_Read (Bmp: TPV_Bitmap; Str: TStream): Boolean;
305431
306432// Atari 4MI
@@ -9658,6 +9784,9 @@ initialization
96589784// BitmapFormats.Add('ozt', @OZT_Read, nil, '');
96599785// BitmapFormats.Add('pgx2', @PGX2_Read, nil, '');
96609786
9787+ BitmapFormats.Add(' lbm' , @LBM_Read, nil , ' Amiga LBM' );
9788+ BitmapFormats.Add(' iff' , @LBM_Read, nil , ' Amiga LBM' );
9789+
96619790 BitmapFormats.Add(' pi4' , @PI4_Read, nil , ' Degas Extended' );
96629791 BitmapFormats.Add(' pi5' , @PI5_Read, nil , ' Degas Extended' ); // medium
96639792 BitmapFormats.Add(' pi7' , @PI7_Read, nil , ' Degas Extended' );
0 commit comments