Changeset 9 for trunk/UGraphic.pas


Ignore:
Timestamp:
Sep 21, 2014, 8:11:48 PM (10 years ago)
Author:
chronos
Message:
  • Modified: Not TGBitmap and TGColor data are stored as TBitMemory to support color formats with lower bit width size then 8.
Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

    • Property svn:ignore
      •  

        old new  
        22LibrePaint
        33lib
         4backup
  • trunk/UGraphic.pas

    r8 r9  
    66
    77uses
    8   Classes, SysUtils, Graphics, Contnrs;
     8  Classes, SysUtils, Graphics, Contnrs, UMemory;
    99
    1010type
     
    1313  TGColor = class;
    1414  TGCanvas = class;
    15 
    16   TGColorClass = class of TGColor;
     15  TGBitmap = class;
    1716
    1817  { TGColorFormat }
     
    2423    function GetChannelBitPos(Channel: TGColorChannel): Integer; virtual;
    2524    function GetChannelBitWidth(Channel: TGColorChannel): Integer; virtual;
     25    function GetChannelStateCount(Channel: TGColorChannel): Integer; virtual;
    2626    function ChannelUsed(Channel: TGColorChannel): Boolean;
    2727    function ColorToTColor(Color: TGColor): TColor; virtual;
    2828    procedure ColorFromTColor(GColor: TGColor; Color: TColor); virtual;
    29     function GetColorClass: TGColorClass; virtual;
    3029  end;
    3130
     
    3736  private
    3837    FColorFormat: TGColorFormat;
    39     FData: PByte;
     38    FData: TBitMemory;
    4039    function GetChannel(Channel: TGColorChannel): TGColor;
    4140    procedure SetColorFormat(AValue: TGColorFormat);
    42     procedure LoadData(BitmapData: Pointer); virtual;
    43     procedure SaveData(BitmapData: Pointer); virtual;
     41    procedure LoadData(Bitmap: TGBitmap; Position: Integer); virtual;
     42    procedure SaveData(Bitmap: TGBitmap; Position: Integer); virtual;
    4443  public
    4544    function ToTColor: TColor;
     
    4847    constructor Create;
    4948    property Channels[Channel: TGColorChannel]: TGColor read GetChannel;
    50     property Data: PByte read FData;
     49    property Data: TBitMemory read FData;
    5150  published
    5251    property Format: TGColorFormat read FColorFormat write SetColorFormat;
     
    6261    FDPI: Integer;
    6362    FSize: TPoint;
    64     FData: PByte;
     63    FData: TBitMemory;
    6564    function GetPixel(X, Y: Integer): TGColor;
    6665    function GetSize: TPoint;
     
    6968    procedure SetPixel(X, Y: Integer; AValue: TGColor);
    7069    procedure SetSize(AValue: TPoint);
    71     function GetPixelDataPos(X, Y: Integer): Pointer;
     70    function GetPixelDataPos(X, Y: Integer): Integer;
     71    procedure CheckLimits(X, Y: Integer);
    7272  public
    7373    function GetDataSize: Integer;
     
    7979    constructor Create; virtual;
    8080    destructor Destroy; override;
     81    property Data: TBitMemory read FData;
    8182    property BackgroundColor: TGColor read FBackgroundColor write SetBackgroundColor;
    8283    property DPI: Integer read FDPI write FDPI;
     
    253254end;
    254255
     256function TGColorFormat.GetChannelStateCount(Channel: TGColorChannel): Integer;
     257begin
     258  Result := 1 shl GetChannelBitWidth(Channel);
     259end;
     260
    255261function TGColorFormat.ChannelUsed(Channel: TGColorChannel): Boolean;
    256262begin
     
    259265
    260266function TGColorFormat.ColorToTColor(Color: TGColor): TColor;
    261 begin
    262   Result := clBlack;
     267var
     268  Channel: TBitMemory;
     269begin
     270  Result := 0;
     271  Channel := TBitMemory.Create;
     272
     273  if GetChannelBitWidth(ccRed) > 0 then begin
     274    Channel.Size := GetChannelBitWidth(ccRed);
     275    Color.Data.ReadBlock(Channel, GetChannelBitPos(ccRed));
     276    Result := Result or (Trunc(Channel.GetInteger * 255 / (GetChannelStateCount(ccRed) - 1)) shl 0);
     277  end;
     278
     279  if GetChannelBitWidth(ccGreen) > 0 then begin
     280    Channel.Size := GetChannelBitWidth(ccGreen);
     281    Color.Data.ReadBlock(Channel, GetChannelBitPos(ccGreen));
     282    Result := Result or (Trunc(Channel.GetInteger * 255 / (GetChannelStateCount(ccGreen) - 1)) shl 8);
     283  end;
     284
     285  if GetChannelBitWidth(ccBlue) > 0 then begin
     286    Channel.Size := GetChannelBitWidth(ccBlue);
     287    Color.Data.ReadBlock(Channel, GetChannelBitPos(ccBlue));
     288    Result := Result or (Trunc(Channel.GetInteger * 255 / (GetChannelStateCount(ccBlue) - 1)) shl 16);
     289  end;
     290
     291  if GetChannelBitWidth(ccGray) > 0 then begin
     292    Channel.Size := GetChannelBitWidth(ccGray);
     293    Color.Data.ReadBlock(Channel, GetChannelBitPos(ccGray));
     294    Result := $010101 * Trunc(Channel.GetInteger * 255 / (GetChannelStateCount(ccGray) - 1));
     295  end;
     296
     297  Channel.Free;
    263298end;
    264299
    265300procedure TGColorFormat.ColorFromTColor(GColor: TGColor; Color: TColor);
    266 begin
    267   FillChar(GColor.Data^, GetPixelSize, 0);
    268 end;
    269 
    270 function TGColorFormat.GetColorClass: TGColorClass;
    271 begin
    272   Result := TGColor;
     301var
     302  Channel: TBitMemory;
     303begin
     304  GColor.Data.Clear(0);
     305  Channel := TBitMemory.Create;
     306
     307  if GetChannelBitWidth(ccRed) > 0 then begin
     308    Channel.Size := GetChannelBitWidth(ccRed);
     309    Channel.SetInteger(((Color shr 0) and $ff) * GetChannelStateCount(ccRed) div 256);
     310    GColor.Data.WriteBlock(Channel, GetChannelBitPos(ccRed));
     311  end;
     312
     313  if GetChannelBitWidth(ccGreen) > 0 then begin
     314    Channel.Size := GetChannelBitWidth(ccGreen);
     315    Channel.SetInteger(((Color shr 8) and $ff) * GetChannelStateCount(ccGreen) div 256);
     316    GColor.Data.WriteBlock(Channel, GetChannelBitPos(ccGreen));
     317  end;
     318
     319  if GetChannelBitWidth(ccBlue) > 0 then begin
     320    Channel.Size := GetChannelBitWidth(ccBlue);
     321    Channel.SetInteger(((Color shr 16) and $ff) * GetChannelStateCount(ccBlue) div 256);
     322    GColor.Data.WriteBlock(Channel, GetChannelBitPos(ccBlue));
     323  end;
     324
     325  if GetChannelBitWidth(ccGray) > 0 then begin
     326    Channel.Size := GetChannelBitWidth(ccGray);
     327    Channel.SetInteger((((Color shr 16) and $ff) + ((Color shr 8) and $ff) + ((Color shr 0) and $ff))
     328      * GetChannelStateCount(ccGray) div (3 * 256));
     329    GColor.Data.WriteBlock(Channel, GetChannelBitPos(ccGray));
     330  end;
     331
     332  Channel.Free;
    273333end;
    274334
     
    284344  if FColorFormat = AValue then Exit;
    285345  FColorFormat := AValue;
    286   ReAllocMem(FData, FColorFormat.GetPixelSize);
    287 end;
    288 
    289 procedure TGColor.LoadData(BitmapData: Pointer);
    290 begin
    291   Move(BitmapData^, FData^, FColorFormat.GetPixelSize);
    292 end;
    293 
    294 procedure TGColor.SaveData(BitmapData: Pointer);
    295 begin
    296   Move(FData^, BitmapData^, FColorFormat.GetPixelSize);
     346  FData.Size := FColorFormat.GetPixelSize;
     347end;
     348
     349procedure TGColor.LoadData(Bitmap: TGBitmap; Position: Integer);
     350begin
     351  Bitmap.Data.ReadBlock(FData, Position);
     352end;
     353
     354procedure TGColor.SaveData(Bitmap: TGBitmap; Position: Integer);
     355begin
     356  Bitmap.Data.WriteBlock(FData, Position);
    297357end;
    298358
     
    313373constructor TGColor.Create;
    314374begin
     375  FData := TBitMemory.Create;
    315376  Format := TGColorFormat.Create;
    316377end;
     
    320381function TGBitmap.GetPixel(X, Y: Integer): TGColor;
    321382begin
     383  CheckLimits(X, Y);
    322384  Result := TGColor.Create;
    323385  Result.Format := ColorFormat;
    324   Result.LoadData(GetPixelDataPos(X, Y));
     386  Result.LoadData(Self, GetPixelDataPos(X, Y));
    325387end;
    326388
     
    340402  if FColorFormat = AValue then Exit;
    341403  FColorFormat := AValue;
    342   ReAllocMem(FData, GetDataSize);
     404  FData.Size := GetDataSize;
    343405  FBackgroundColor.Format := ColorFormat;
    344406end;
     
    346408procedure TGBitmap.SetPixel(X, Y: Integer; AValue: TGColor);
    347409begin
    348   AValue.SaveData(GetPixelDataPos(X, Y));
     410  CheckLimits(X, Y);
     411  FData.WriteBlock(AValue.Data, GetPixelDataPos(X, Y));
    349412end;
    350413
     
    353416  if (FSize.X = AValue.X) and (FSize.Y = AValue.Y) then Exit;
    354417  FSize := AValue;
    355   ReAllocMem(FData, GetDataSize);
    356 end;
    357 
    358 function TGBitmap.GetPixelDataPos(X, Y: Integer): Pointer;
    359 begin
    360   Result := FData + X * FColorFormat.GetPixelSize + Y * FColorFormat.GetPixelSize * FSize.X;
     418  FData.Size := GetDataSize;
     419end;
     420
     421function TGBitmap.GetPixelDataPos(X, Y: Integer): Integer;
     422begin
     423  Result := X * FColorFormat.GetPixelSize + Y * FColorFormat.GetPixelSize * FSize.X;
     424end;
     425
     426procedure TGBitmap.CheckLimits(X, Y: Integer);
     427begin
     428  if (X < 0) or (Y < 0) or (X >= Size.X) or (Y >= Size.Y) then
     429    raise Exception.Create('Out of range');
    361430end;
    362431
     
    399468  X, Y: Integer;
    400469  Color: TGColor;
     470  F: Cardinal;
    401471begin
    402472  Color := TGColor.Create;
     
    405475    for X := 0 to Size.X - 1 do begin
    406476      Color.FromTColor(System.Random($ffffff));
     477      F := Cardinal(Color.Data.GetInteger);
     478
    407479      Pixels[X, Y] := Color;
    408480    end;
     
    440512constructor TGBitmap.Create;
    441513begin
    442   FData := GetMem(0);
     514  FData := TBitMemory.Create;
    443515  FBackgroundColor := TGColor.Create;
    444516  ColorFormat := TGColorFormat.Create;
     
    451523destructor TGBitmap.Destroy;
    452524begin
     525  Size := Point(0, 0);
     526  FData.Free;
    453527  inherited Destroy;
    454   Size := Point(0, 0);
    455528end;
    456529
Note: See TracChangeset for help on using the changeset viewer.