GLS.FilePGM.pas 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. //
  2. // The multimedia graphics platform GLScene https://github.com/glscene
  3. //
  4. unit GLS.FilePGM;
  5. (* PGM image loader *)
  6. {$I GLScene.inc}
  7. interface
  8. uses
  9. Winapi.OpenGL,
  10. System.Classes,
  11. System.SysUtils,
  12. GLS.Context,
  13. GLS.Graphics,
  14. GLS.TextureFormat,
  15. GLS.Strings,
  16. GLS.ApplicationFileIO,
  17. CUDA.Utility;
  18. type
  19. TGLPGMImage = class(TGLBaseImage)
  20. public
  21. class function Capabilities: TGLDataFileCapabilities; override;
  22. procedure LoadFromFile(const filename: string); override;
  23. procedure SaveToFile(const filename: string); override;
  24. procedure LoadFromStream(stream: TStream); override;
  25. procedure SaveToStream(stream: TStream); override;
  26. procedure AssignFromTexture(textureContext: TGLContext;
  27. const textureHandle: Cardinal; textureTarget: TGLTextureTarget;
  28. const CurrentFormat: Boolean; const intFormat: TGLInternalFormat);
  29. reintroduce;
  30. end;
  31. // ------------------------------------------------------------------
  32. implementation
  33. // ------------------------------------------------------------------
  34. // ------------------
  35. // ------------------ TGLPGMImage ------------------
  36. // ------------------
  37. procedure TGLPGMImage.LoadFromFile(const filename: string);
  38. var
  39. w, h: Integer;
  40. cutBuffer: System.PSingle;
  41. begin
  42. if FileExists(filename) then
  43. begin
  44. if not IsCUTILInitialized then
  45. if not InitCUTIL then
  46. begin
  47. EInvalidRasterFile.Create(strCUTILFailed);
  48. exit;
  49. end;
  50. cutBuffer := nil;
  51. if cutLoadPGMf(PAnsiChar(AnsiString(filename)), cutBuffer, w, h) then
  52. begin
  53. ResourceName := filename;
  54. UnMipmap;
  55. FLOD[0].Width := w;
  56. FLOD[0].Height := h;
  57. FLOD[0].Depth := 0;
  58. fColorFormat := GL_LUMINANCE;
  59. fInternalFormat := tfLUMINANCE_FLOAT32;
  60. fDataType := GL_FLOAT;
  61. fCubeMap := false;
  62. fTextureArray := false;
  63. fElementSize := GetTextureElementSize(tfLUMINANCE_FLOAT32);
  64. ReallocMem(fData, DataSize);
  65. Move(cutBuffer^, fData^, DataSize);
  66. cutFree(cutBuffer);
  67. end;
  68. end
  69. else
  70. raise EInvalidRasterFile.CreateFmt('File %s not found', [filename]);
  71. end;
  72. procedure TGLPGMImage.SaveToFile(const filename: string);
  73. begin
  74. if not IsCUTILInitialized then
  75. if not InitCUTIL then
  76. begin
  77. EInvalidRasterFile.Create(strCUTILFailed);
  78. exit;
  79. end;
  80. if not cutSavePGMf(PAnsiChar(AnsiString(filename)), System.PSingle(fData),
  81. FLOD[0].Width, FLOD[0].Height) then
  82. raise EInvalidRasterFile.Create('Saving to file failed');
  83. end;
  84. procedure TGLPGMImage.LoadFromStream(stream: TStream);
  85. begin
  86. Assert(false, 'Stream loading not supported');
  87. end;
  88. procedure TGLPGMImage.SaveToStream(stream: TStream);
  89. begin
  90. Assert(false, 'Stream saving not supported');
  91. end;
  92. procedure TGLPGMImage.AssignFromTexture(textureContext: TGLContext;
  93. const textureHandle: Cardinal; textureTarget: TGLTextureTarget;
  94. const CurrentFormat: Boolean; const intFormat: TGLInternalFormat);
  95. var
  96. oldContext: TGLContext;
  97. contextActivate: Boolean;
  98. texFormat: Cardinal;
  99. residentFormat: TGLInternalFormat;
  100. glTarget: Cardinal;
  101. begin
  102. if not((textureTarget = ttTexture2D) or (textureTarget = ttTextureRect)) then
  103. exit;
  104. oldContext := CurrentGLContext;
  105. contextActivate := (oldContext <> textureContext);
  106. if contextActivate then
  107. begin
  108. if Assigned(oldContext) then
  109. oldContext.Deactivate;
  110. textureContext.Activate;
  111. end;
  112. glTarget := DecodeTextureTarget(textureTarget);
  113. try
  114. textureContext.GLStates.TextureBinding[0, textureTarget] := textureHandle;
  115. fLevelCount := 0;
  116. fCubeMap := false;
  117. fTextureArray := false;
  118. fColorFormat := GL_LUMINANCE;
  119. fDataType := GL_FLOAT;
  120. // Check level existence
  121. gl.GetTexLevelParameteriv(glTarget, 0, GL_TEXTURE_INTERNAL_FORMAT,
  122. @texFormat);
  123. if texFormat > 1 then
  124. begin
  125. gl.GetTexLevelParameteriv(glTarget, 0, GL_TEXTURE_WIDTH, @FLOD[0].Width);
  126. gl.GetTexLevelParameteriv(glTarget, 0, GL_TEXTURE_HEIGHT,
  127. @FLOD[0].Height);
  128. FLOD[0].Depth := 0;
  129. residentFormat := OpenGLFormatToInternalFormat(texFormat);
  130. if CurrentFormat then
  131. fInternalFormat := residentFormat
  132. else
  133. fInternalFormat := intFormat;
  134. Inc(fLevelCount);
  135. end;
  136. if fLevelCount > 0 then
  137. begin
  138. fElementSize := GetTextureElementSize(fColorFormat, fDataType);
  139. ReallocMem(fData, DataSize);
  140. gl.GetTexImage(glTarget, 0, fColorFormat, fDataType, fData);
  141. end
  142. else
  143. fLevelCount := 1;
  144. gl.CheckError;
  145. finally
  146. if contextActivate then
  147. begin
  148. textureContext.Deactivate;
  149. if Assigned(oldContext) then
  150. oldContext.Activate;
  151. end;
  152. end;
  153. end;
  154. class function TGLPGMImage.Capabilities: TGLDataFileCapabilities;
  155. begin
  156. Result := [dfcRead, dfcWrite];
  157. end;
  158. //------------------------------------------------
  159. initialization
  160. //------------------------------------------------
  161. RegisterRasterFormat('pgm', 'Portable Graymap', TGLPGMImage);
  162. end.