<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Word 14 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0in;
margin-bottom:.0001pt;
font-size:11.0pt;
font-family:"Calibri","sans-serif";}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{mso-style-priority:99;
color:purple;
text-decoration:underline;}
span.EmailStyle17
{mso-style-type:personal-compose;
font-family:"Calibri","sans-serif";
color:windowtext;}
.MsoChpDefault
{mso-style-type:export-only;
font-family:"Calibri","sans-serif";}
@page WordSection1
{size:8.5in 11.0in;
margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
{page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal">I’m trying to use gdal.FileFromMemBuffer to do some in-memory processing, but I ran into what seems to be a 2 GB limit.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">If I create a TIF on disk that is just below 2 GB, things work fine:<o:p></o:p></p>
<p class="MsoNormal">import gdal<o:p></o:p></p>
<p class="MsoNormal">drv = gdal.GetDriverByName("GTiff")<o:p></o:p></p>
<p class="MsoNormal">ds = drv.Create("45000.tif", 45000, 45000, 1, gdal.GDT_Byte)<o:p></o:p></p>
<p class="MsoNormal">ds = None<o:p></o:p></p>
<p class="MsoNormal">with open("45000.tif", "r") as f:<o:p></o:p></p>
<p class="MsoNormal"> membuf = f.read()<o:p></o:p></p>
<p class="MsoNormal">gdal.FileFromMemBuffer("/vsimem/45000.tif", membuf)<o:p></o:p></p>
<p class="MsoNormal">ds = gdal.Open("/vsimem/45000.tif")<o:p></o:p></p>
<p class="MsoNormal">print(ds.RasterXSize) -> Prints “45000”<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">If I repeat this process with a file that is just over 2 GB:<o:p></o:p></p>
<p class="MsoNormal">import gdal<o:p></o:p></p>
<p class="MsoNormal">drv = gdal.GetDriverByName("GTiff")<o:p></o:p></p>
<p class="MsoNormal">ds = drv.Create("48000.tif", 48000, 48000, 1, gdal.GDT_Byte)<o:p></o:p></p>
<p class="MsoNormal">ds = None<o:p></o:p></p>
<p class="MsoNormal">with open("48000.tif", "r") as f:<o:p></o:p></p>
<p class="MsoNormal"> membuf = f.read()<o:p></o:p></p>
<p class="MsoNormal">gdal.FileFromMemBuffer("/vsimem/48000.tif", membuf)<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">On OSX, I get this error:<o:p></o:p></p>
<p class="MsoNormal">python2.7(30843,0x7fffa80063c0) malloc: *** mach_vm_map(size=18446744071718969344) failed (error code=3)<o:p></o:p></p>
<p class="MsoNormal">*** error: can't allocate region<o:p></o:p></p>
<p class="MsoNormal">*** set a breakpoint in malloc_error_break to debug<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">On Linux, I get no error but if I try to ds = gdal.Open(“/vsimem/48000.tif”) I get a “no such file or directory” error.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">I found this SWIG wrapper function in swig/include/cpl.i:<o:p></o:p></p>
<p class="MsoNormal">void wrapper_VSIFileFromMemBuffer( const char* utf8_path, int nBytes, const GByte *pabyData)<o:p></o:p></p>
<p class="MsoNormal">{<o:p></o:p></p>
<p class="MsoNormal"> GByte* pabyDataDup = (GByte*)VSIMalloc(nBytes);<o:p></o:p></p>
<p class="MsoNormal"> if (pabyDataDup == NULL)<o:p></o:p></p>
<p class="MsoNormal"> return;<o:p></o:p></p>
<p class="MsoNormal"> memcpy(pabyDataDup, pabyData, nBytes);<o:p></o:p></p>
<p class="MsoNormal"> VSIFCloseL(VSIFileFromMemBuffer(utf8_path, (GByte*) pabyDataDup, nBytes, TRUE));<o:p></o:p></p>
<p class="MsoNormal">}<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">It seems like the input “int nBytes” is the problem, as it is passed to VSIMalloc whicih takes a size_t type. The int type is signed and 32-bit so it can’t handle over 2 * 2^30 (2 GB). It’s probably rolling over, then when cast to size_t
it is interpreted as that huge size in the OSX error message.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Also, is there any plan to expose the boolean that controls whether it takes ownership of the passed in buffer? As it is now, calling this function requires 2x the memory because of the malloc and memcpy. Maybe the ownership of the buffer
is too tricky when dealing with multiple languages and reference counting...<o:p></o:p></p>
</div>
<br>
This electronic communication and any attachments may contain confidential and proprietary information of DigitalGlobe, Inc. If you are not the intended recipient, or an agent or employee responsible for delivering this communication to the intended recipient,
or if you have received this communication in error, please do not print, copy, retransmit, disseminate or otherwise use the information. Please indicate to the sender that you have received this communication in error, and delete the copy you received.
<br>
<br>
DigitalGlobe reserves the right to monitor any electronic communication sent or received by its employees, agents or representatives.
</body>
</html>