PageRenderTime 26ms CodeModel.GetById 37ms RepoModel.GetById 1ms app.codeStats 0ms

/GR32Ex/GR_AnimationGif.pas

http://gr32ex.googlecode.com/
Pascal | 222 lines | 163 code | 25 blank | 34 comment | 19 complexity | 6e391c22649234accfe2f6992709829e MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception
  1. (* ***** BEGIN LICENSE BLOCK *****
  2. * Version: MPL 1.1
  3. *
  4. * The contents of this file are subject to the Mozilla Public License Version
  5. * 1.1 (the "License"); you may not use this file except in compliance with
  6. * the License. You may obtain a copy of the License at
  7. * http://www.mozilla.org/MPL/
  8. *
  9. * Software distributed under the License is distributed on an "AS IS" basis,
  10. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11. * for the specific language governing rights and limitations under the
  12. * License.
  13. *
  14. * The Original Code is GR_AnimationGif
  15. *
  16. * The Initial Developer of the Original Code is Michael Faust
  17. * Portions created by Michael Faust - http://www.alpha-interactive.de/ are Copyright (C) 2000-2005
  18. * Portions created by Riceball LEE are Copyright (C) 2008
  19. * All Rights Reserved.
  20. *
  21. * Contributor(s):
  22. *
  23. * ***** END LICENSE BLOCK ***** *)
  24. unit GR_AnimationGif;
  25. interface
  26. uses
  27. Windows, Messages, Classes, Graphics, Controls
  28. , GR32
  29. , GR_Animation
  30. , GifImage
  31. ;
  32. type
  33. TGRAnimationGif = class(TGRAnimation)
  34. private
  35. protected
  36. function GetFrameDelay(const FrameIndex: Integer; const SafeMode: Boolean=True): Integer;override;
  37. public
  38. procedure LoadFromStream(const S: TStream); override;
  39. procedure SaveToStream(const aStream: TStream);override;
  40. published
  41. end;
  42. implementation
  43. { TGRAnimationGif }
  44. function TGRAnimationGif.GetFrameDelay(const FrameIndex: Integer; const SafeMode: Boolean=True): Integer;
  45. begin
  46. Result := 0;
  47. if IndexIsValid(FrameIndex) then
  48. Result := FFrames.Items[FrameIndex].DelayTime;
  49. if SafeMode then
  50. begin
  51. if (Result > GIFMaximumDelay) then
  52. Result := GIFMaximumDelay
  53. else if (Result < GIFMinimumDelay) then
  54. begin
  55. if (Result = 0) then
  56. Result := GIFDefaultDelay
  57. else
  58. Result := GIFMinimumDelay;
  59. end;
  60. end;
  61. // this is called "cheating" ... hehehe.
  62. Result := Result * 10 + 4;
  63. end;
  64. procedure TGRAnimationGif.LoadFromStream(const S: TStream);
  65. var
  66. I, TotalCount: Integer;
  67. AGif: TGifImage;
  68. SubGif: TGifSubImage;
  69. FrameItem: TGRAnimationFrame;
  70. ACanvas: TCanvas;
  71. bgClr: TColor;
  72. doClearBackupAfter,
  73. doClearBackupFirst,
  74. doCopyLastFrame,
  75. doGetBackup: Boolean;
  76. newDisposal,
  77. oldDisposal : TDisposalMethod;
  78. Bmp32Backup,
  79. Bmp32Frame: TBitmap32;
  80. begin
  81. FFrames.Clear;
  82. AGif := TGifImage.Create;
  83. Bmp32Backup := TBitmap32.Create;
  84. Bmp32Frame := TBitmap32.Create;
  85. try
  86. OldDisposal := dmNoDisposal;
  87. AGif.LoadFromStream(S);
  88. Bmp32Frame.SetSize(AGif.Width, AGif.Height);
  89. //Bmp32Frame.ResamplerClassName := Self.OriginalFilter;
  90. Bmp32Backup.SetSize(AGif.Width, AGif.Height);
  91. //Bmp32Backup.ResamplerClassName := Self.OriginalFilter;
  92. TotalCount := AGif.Images.Count;
  93. bgClr := BackgroundColor;
  94. for I := 0 to TotalCount -1 do
  95. begin
  96. bgClr := BackgroundColor;
  97. //PerformFrameLoad(Self, I, TotalCount, bgClr);
  98. SubGif := AGif.Images.SubImages[I];
  99. if (not Assigned(SubGif)) or (SubGif.Empty) then
  100. Continue; // ignore empty frames
  101. // if (I = 0) then
  102. begin
  103. Bmp32Frame.Clear(Color32(bgClr));
  104. if (I = 0) then
  105. Bmp32Backup.Clear(Color32(bgClr));
  106. end;
  107. if Assigned(SubGif.GraphicControlExtension) then
  108. newDisposal := SubGif.GraphicControlExtension.Disposal
  109. else
  110. newDisposal := dmNoDisposal;
  111. ACanvas := TCanvas.Create;
  112. try
  113. doGetBackup := false;
  114. doClearBackupAfter := false;
  115. doClearBackupFirst := false;
  116. doCopyLastFrame := false;
  117. case newDisposal of
  118. dmNone,
  119. dmNoDisposal:
  120. begin
  121. doGetBackup := true;
  122. ACanvas.Handle := Bmp32Backup.Handle;
  123. doCopyLastFrame := true;
  124. end;
  125. dmBackground:
  126. begin
  127. ACanvas.Handle := Bmp32Frame.Handle;
  128. doClearBackupAfter := true;
  129. doCopyLastFrame := true;
  130. end;
  131. dmPrevious:
  132. begin
  133. doGetBackup := true;
  134. ACanvas.Handle := Bmp32Backup.Handle;
  135. case oldDisposal of
  136. dmNone, dmNoDisposal:
  137. begin
  138. ACanvas.Handle := Bmp32Backup.Handle;
  139. end;
  140. dmBackground, dmPrevious:
  141. begin
  142. ACanvas.Handle := Bmp32Backup.Handle;
  143. doClearBackupFirst := True;
  144. doCopyLastFrame := True;
  145. end;
  146. end;
  147. end;
  148. end;
  149. OldDisposal := newDisposal;
  150. // Already a frame loaded.
  151. if (I > 0) then
  152. begin
  153. if doClearBackupFirst then
  154. Bmp32Backup.Clear(Color32(bgClr));
  155. if doCopyLastFrame then
  156. Bmp32Frame.Assign(Bmp32Backup);
  157. SubGif.Draw(ACanvas, Rect(0, 0, AGif.Width, AGif.Height), true, false);
  158. if doClearBackupAfter then
  159. Bmp32Backup.Clear(Color32(bgClr))
  160. end else begin
  161. SubGif.Draw(ACanvas, Rect(0, 0, AGif.Width, AGif.Height), true, false);
  162. end;
  163. finally
  164. ACanvas.Free;
  165. end;
  166. FrameItem := FFrames.Add;
  167. if Assigned(SubGif.GraphicControlExtension) then
  168. FrameItem.DelayTime := SubGif.GraphicControlExtension.Delay
  169. else
  170. FrameItem.DelayTime := GIFDefaultDelay;
  171. // Backgroundcolor for transperancy
  172. FrameItem.BackgroundColor := bgClr;
  173. // the stretch filter has to be assigned to each single bitmap32
  174. // FrameItem.Bitmap.StretchFilter := Self.OriginalFilter;
  175. if (doGetBackup) then
  176. begin
  177. FrameItem.Bitmap.Assign(Bmp32Backup);
  178. // Bmp32Frame.Assign(Bmp32Backup);
  179. end else begin
  180. FrameItem.Bitmap.Assign(Bmp32Frame);
  181. if not (doClearBackupAfter or doClearBackupFirst) then
  182. Bmp32Backup.Assign(Bmp32Frame);
  183. end;
  184. end;
  185. finally
  186. AGif.Free;
  187. Bmp32Backup.Free;
  188. Bmp32Frame.Free;
  189. end;
  190. RequestFlipAlphaChannel;
  191. end;
  192. procedure TGRAnimationGif.SaveToStream(const aStream: TStream);
  193. begin
  194. end;
  195. Initialization
  196. RegisterAnimation('gif', '', TGRAnimationGif);
  197. end.