| 
    E57 Simple API V1.0.312
    Aug. 10, 2012
    
   | 
 
This browser-based document describes the E57 Simple API (Application Programmer Interface) version 0.52, which is a collection of functions that help a C++ programmer wrap the E57 Foundation API.
An example of a typical use of this interface would be as follows: 
        try
        {
Create a ReaderImpl
                _bstr_t bsFile = sFile;                 //converts Unicode to UTF-8
                e57::Reader     eReader( (char*) bsFile);
///////////////////////////////////////////////////////////// ACCESSING ROOT DATA
Read the root
e57::E57Root rootHeader; eReader.GetE57Root( rootHeader);
Access all the root information like
                char* fileGuid = rootHeader.guid.c_str();
                double fileGPSTime = rootHeader.creationDateTime;
                ...
///////////////////////////////////////////////////////////// ACCESSING SCAN DATA3D
Get the number of scan images available
int data3DCount = eReader.GetData3DCount();
selecting the first scan
int scanIndex = 0;
Read the scan 0 header.
e57::Data3D scanHeader; eReader.ReadData3D( scanIndex, scanHeader);
Access all the header information
                _bstr_t bstrName = scanHeader.name.c_str();
                _bstr_t bstrGuid = scanHeader.guid.c_str();
                _bstr_t bstrDesc = scanHeader.description.c_str();
                double startGPSTime = rootHeader.acquisitionStart;
                double endGPSTime = rootHeader.acquisitionEnd;
Get pose information
                ISI::Point translation;
                translation.x(scanHeader.pose.translation.x);
                translation.y(scanHeader.pose.translation.y);
                translation.z(scanHeader.pose.translation.z);
                ISI::Quat rotation;
                rotation.w(scanHeader.pose.rotation.w);
                rotation.x(scanHeader.pose.rotation.x);
                rotation.y(scanHeader.pose.rotation.y);
                rotation.z(scanHeader.pose.rotation.z);
Get scanner information
                _bstr_t bstrSerial = scanHeader.sensorSerialNumber.c_str();
                _bstr_t bstrVendor = scanHeader.sensorVendor.c_str();
                _bstr_t bstrModel = scanHeader.sensorModel.c_str();
                _bstr_t bstrSoftware = scanHeader.sensorSoftwareVersion.c_str();
                _bstr_t bstrFirmware = scanHeader.sensorFirmwareVersion.c_str();
                _bstr_t bstrHardware = scanHeader.sensorHardwareVersion.c_str();
Get environment information
                double temperature = scanHeader.temperature;
                double humidity = scanHeader.relativeHumidity;
                double airPressure = scanHeader.atmosphericPressure;
...
/////////////////////////////////////////////////////////////// ACCESSING SCAN DATA
Get the Size of the Scan
                int64_t nColumn = 0;    
                int64_t nRow = 0;
int64_t nPointsSize = 0; //Number of points
                int64_t nGroupsSize = 0;        //Number of groups
                int64_t nCountSize = 0;         //Number of points per group
                bool    bColumnIndex = false; //indicates that idElementName is "columnIndex"
eReader.GetData3DSizes( scanIndex, nRow, nColumn, nPointsSize, nGroupsSize, nCountSize, bColumnIndex);
                int64_t nSize = nRow;
                if(nSize == 0) nSize = 1024;    // choose a chunk size
Setup buffers
                int8_t * isInvalidData = NULL;
                if(scanHeader.pointFields.cartesianInvalidStateField)
                        isInvalidData = new int8_t[nSize];
Setup Points Buffers
                double * xData = NULL;
                if(scanHeader.pointFields.cartesianXField)
                        xData = new double[nSize];
                double * yData = NULL;
                if(scanHeader.pointFields.cartesianYField)
                        yData = new double[nSize];
                double * zData = NULL;
                if(scanHeader.pointFields.cartesianZField)
                        zData = new double[nSize];
Setup intensity buffers if present
                double *        intData = NULL;
                bool            bIntensity = false;
                double          intRange = 0;
                double          intOffset = 0;
                if(scanHeader.pointFields.intensityField)
                {
                        bIntensity = true;
                        intData = new double[nSize];
                        intRange = scanHeader.intensityLimits.intensityMaximum - scanHeader.intensityLimits.intensityMinimum;
                        intOffset = scanHeader.intensityLimits.intensityMinimum;
                }
Setup color buffers if present
                uint16_t *      redData = NULL;
                uint16_t *      greenData = NULL;
                uint16_t *      blueData = NULL;
                bool            bColor = false;
                int32_t         colorRedRange = 1;
                int32_t         colorRedOffset = 0;
                int32_t         colorGreenRange = 1;
                int32_t         colorGreenOffset = 0;
                int32_t         colorBlueRange = 1;
                int32_t         colorBlueOffset = 0;
                if(header.pointFields.colorRedField)
                {
                        bColor = true;
                        redData = new uint16_t[nSize];
                        greenData = new uint16_t[nSize];
                        blueData = new uint16_t[nSize];
                        colorRedRange = header.colorLimits.colorRedMaximum - header.colorLimits.colorRedMinimum;
                        colorRedOffset = header.colorLimits.colorRedMinimum;
                        colorGreenRange = header.colorLimits.colorGreenMaximum - header.colorLimits.colorGreenMinimum;
                        colorGreenOffset = header.colorLimits.colorGreenMinimum;
                        colorBlueRange = header.colorLimits.colorBlueMaximum - header.colorLimits.colorBlueMinimum;
                        colorBlueOffset = header.colorLimits.colorBlueMinimum;
                }
Setup the GroupByLine buffers information
                int64_t * idElementValue = NULL;
                int64_t * startPointIndex = NULL;
                int64_t * pointCount = NULL;
                if(nGroupsSize > 0)
                {
                        idElementValue = new int64_t[nGroupsSize];
                        startPointIndex = new int64_t[nGroupsSize];
                        pointCount = new int64_t[nGroupsSize];
                        if(!eReader.ReadData3DGroupsData(scanIndex, nGroupsSize, idElementValue,
                                startPointIndex, pointCount))
                                nGroupsSize = 0;
                }
Setup row/column index information
                int32_t * rowIndex = NULL;
                int32_t * columnIndex = NULL;
                if(scanHeader.pointFields.rowIndexField)
                        rowIndex = new int32_t[nSize];
                if(scanHeader.pointFields.columnIndexField)
                        columnIndex = new int32_t[nRow];
Get dataReader object
                e57::CompressedVectorReader dataReader = eReader.SetUpData3DPointsData(
                                scanIndex,                      //!< data block index given by the NewData3D
                                nRow,                           //!< size of each of the buffers given
                                xData,                          //!< pointer to a buffer with the x data
                                yData,                          //!< pointer to a buffer with the y data
                                zData,                          //!< pointer to a buffer with the z data
                                isInvalidData,          //!< pointer to a buffer with the valid indication
                                intData,                        //!< pointer to a buffer with the lidar return intesity
                                NULL,
                                redData,                        //!< pointer to a buffer with the color red data
                                greenData,                      //!< pointer to a buffer with the color green data
                                blueData,                       //!< pointer to a buffer with the color blue data
                                NULL,
                                NULL,
                                NULL,
                                NULL,
                                rowIndex,                       //!< pointer to a buffer with the rowIndex
                                columnIndex                     //!< pointer to a buffer with the columnIndex
                                );
Read the point data
                int64_t         count = 0;
                unsigned        size = 0;
                int                     col = 0;
                int                     row = 0;
                while(size = dataReader.read())
                {
Use the data
                        for(long i = 0; i < size; i++)
                        {
                                if(columnIndex)
                                        col = columnIndex[i];
                                else
                                        col = 0;        //point cloud case
                                if(rowIndex)
                                        row = rowIndex[i];
                                else
                                        row = count;    //point cloud case
                                if(isInvalidData[i] == 0)
                                        pScan->SetPoint(row, col, xData[i], yData[i], zData[i]);
                                if(bIntensity){         //Normalize intensity to 0 - 1.
                                        double intensity = (intData[i] - intOffset)/intRange;
                                        pScan->SetIntensity(row, col, intensity);
                                }
                                if(bColor){                     //Normalize color to 0 - 255
                                        int red = ((redData[i] - colorRedOffset) * 255)/colorRedRange;
                                        int green = ((greenData[i] - colorGreenOffset) * 255)/colorBlueRange;
                                        int blue = ((blueData[i] - colorBlueOffset) * 255)/colorBlueRange;
                                        pScan->SetColor(row, col, red, green, blue);
                                count++;
                        }
                }
Close and clean up
                dataReader.close();
                if(isInvalidData) delete isInvalidData;
                if(xData) delete xData;
                if(yData) delete yData;
                if(zData) delete zData;
                if(intData) delete intData;
                if(redData) delete redData;
                if(greenData) delete greenData;
                if(blueData) delete blueData;
///////////////////////////////////////////////////////////////////// ACCESSING PICTURE IMAGE2D
Get the number of picture images available
int image2DCount = eReader.GetImage2DCount();
selecting the first picture image
int imageIndex = 0;
Read the picture 0 header.
e57::Image2D imageHeader; eReader.ReadImage2D( imageIndex, imageHeader);
Access all the header information
                _bstr_t bstrName = imageHeader.name.c_str();
                _bstr_t bstrGuid = imageHeader.guid.c_str();
                _bstr_t bstrDesc = imageHeader.description.c_str();
                double imageGPSTime = rootHeader.acquisitionDateTime;
Get pose information
                ISI::Point translation;
                translation.x(imageHeader.pose.translation.x);
                translation.y(imageHeader.pose.translation.y);
                translation.z(imageHeader.pose.translation.z);
                ISI::Quat rotation;
                rotation.w(imageHeader.pose.rotation.w);
                rotation.x(imageHeader.pose.rotation.x);
                rotation.y(imageHeader.pose.rotation.y);
                rotation.z(imageHeader.pose.rotation.z);
Get camera information
                _bstr_t bstrSerial = imageHeader.sensorSerialNumber.c_str();
                _bstr_t bstrVendor = imageHeader.sensorVendor.c_str();
                _bstr_t bstrModel = imageHeader.sensorModel.c_str();
                ...
///////////////////////////////////////////////////////////////////// ACCESSING PICTURE IMAGE
Get the Size of the Picture
                e57::Image2DProjection  imageProjection;        //like E57_SPHERICAL
                e57::Image2DType                imageType;                      //like E57_JPEG_IMAGE
                int64_t                                 nImageWidth = 0;        
                int64_t                                 nImageHeight = 0;
                int64_t                                 nImagesSize = 0;        //Number of bytes in the image
                e57::Image2DType                imageMaskType;          //like E57_PNG_IMAGE_MASK if present
                e57::Image2dType                imageVisualType;        //like E57_JPEG_IMAGE if present
                eReader.GetImage2DSizes( imageIndex, imageProjection, imageType,
                        nImageWidth, nImageHeight, nImagesSize, imageMaskType, imageVisualType);
Get pixel information off the sphericalRepresentation if imageProjection == E57_SPHERICAL
                int32_t imageHeight = imageHeader.sphericalRepresentation.imageHeight;
                int32_t imageWidth = imageHeader.sphericalRepresentation.imageWidth;
                double pixelHeight = imageHeader.sphericalRepresentation.pixelHeight;
                double pixelWidth = imageHeader.sphericalRepresentation.pixelWidth;
Set up buffers
void* jpegBuffer = new char[nImagesSize];
Read the picture data
eReader.ReadImage2DData(imageIndex, imageProjection, imageType, jpegBuffer, 0, nImagesSizw);
... access the picture and decode ...
Close and clean up
delete jpegBuffer;
eReaer.Close();
///////////////////////////////////////////////////////////////////// CATCH THE ERRORS
        } catch(E57Exception& ex) {
                ex.report(__FILE__, __LINE__, __FUNCTION__);
        } catch (std::exception& ex) {
                cerr << "Got an std::exception, what=" << ex.what() << endl;
        } catch (...) {
                cerr << "Got an unknown exception" << endl;
        }
An example of a typical use of this interface would be as follows: 
        try
        {
Create a WriterImpl
                _bstr_t bsFile = sFile;                 //converts Unicode to UTF-8
                e57::Writer     eWriter( (char*) bsFile);
                if(!eWriter.IsOpen())                   //test for being open
                        return false;
///////////////////////////////////////////////////////////// SETTING UP SCAN DATA3D
e57::Data3D scanHeader;
Setup the Name and Description
                scanHeader.name = (char*) bstrName;
                scanHeader.description = (char*) bstrDesc;
Setup the GUID
                GUID    guid;                                   //Window's GUID 
                pScan->GetGuid(&guid);
                OLECHAR wbuffer[64];
                StringFromGUID2(guid,&wbuffer[0],64);
                _bstr_t bstrScanGuid = &wbuffer[0];
scanHeader.guid = (char*) bstrScanGuid;
                scanHeader.acquisitionStart.SetCurrentGPSTime();        //use real time
                scanHeader.acquisitionEnd.SetCurrentGPSTime();
Setup the scan size
                scanHeader.indexBounds.rowMaximum = nRow - 1;   
                scanHeader.indexBounds.rowMinimum = 0;
                scanHeader.indexBounds.columnMaximum = nColumn - 1;
                scanHeader.indexBounds.columnMinimum = 0;
                scanHeader.indexBounds.returnMaximum = 0; 
                scanHeader.indexBounds.returnMinimum = 0;
Setup GroupByLine information
                scanHeader.pointGroupingSchemes.groupingByLine.groupsSize = nColumn;
                scanHeader.pointGroupingSchemes.groupingByLine.pointCountSize = nRow;
                scanHeader.pointGroupingSchemes.groupingByLine.idElementName = "columnIndex";
Set up total number of points
scanHeader.pointsSize = (nColumn * nRow);
Setup bounds
                if(exportStatistics)                    
                {       //because we are using scaled integers for the data, we must adjust our bounds
                        scanHeader.cartesianBounds.xMaximum = floor(pStat->GetMaxX()/DATA_SCALE_FACTOR +0.5) * DATA_SCALE_FACTOR;
                        scanHeader.cartesianBounds.xMinimum = floor(pStat->GetMinX()/DATA_SCALE_FACTOR +0.5) * DATA_SCALE_FACTOR;
                        scanHeader.cartesianBounds.yMaximum = floor(pStat->GetMaxY()/DATA_SCALE_FACTOR +0.5) * DATA_SCALE_FACTOR;
                        scanHeader.cartesianBounds.yMinimum = floor(pStat->GetMinY()/DATA_SCALE_FACTOR +0.5) * DATA_SCALE_FACTOR;
                        scanHeader.cartesianBounds.zMaximum = floor(pStat->GetMaxZ()/DATA_SCALE_FACTOR +0.5) * DATA_SCALE_FACTOR;
                        scanHeader.cartesianBounds.zMinimum = floor(pStat->GetMinZ()/DATA_SCALE_FACTOR +0.5) * DATA_SCALE_FACTOR;
                        scanHeader.sphericalBounds.rangeMaximum = floor(pStat->GetMaxRange()/DATA_SCALE_FACTOR +0.5) * DATA_SCALE_FACTOR;
                        scanHeader.sphericalBounds.rangeMinimum = floor(pStat->GetMinRange()/DATA_SCALE_FACTOR +0.5) * DATA_SCALE_FACTOR;
                        scanHeader.sphericalBounds.azimuthEnd = pStat->GetMaxAzimuth();
                        scanHeader.sphericalBounds.azimuthStart = pStat->GetMinAzimuth();
                        scanHeader.sphericalBounds.elevationMaximum = pStat->GetMaxPolar();
                        scanHeader.sphericalBounds.elevationMinimum = pStat->GetMinPolar();
                }
Setup pose rotation and transformation
                if(exportMatrix)                                
                {
                        scanHeader.pose.rotation.w = rotation.w();
                        scanHeader.pose.rotation.x = rotation.x();
                        scanHeader.pose.rotation.y = rotation.y();
                        scanHeader.pose.rotation.z = rotation.z();
                        scanHeader.pose.translation.x = translation.x();
                        scanHeader.pose.translation.y = translation.y();
                        scanHeader.pose.translation.z = translation.z();
                }
Setup scanner information
                if(exportScanner)
                {
                        scanHeader.sensorSerialNumber = (char*) bstrSerial;
                        scanHeader.sensorVendor = (char*) bstrVendor;
                        scanHeader.sensorModel = (char*) bstrModel;
                        scanHeader.sensorSoftwareVersion = (char*) bstrSoftware;
                        scanHeader.sensorFirmwareVersion = (char*) bstrFirmware;
                        scanHeader.sensorHardwareVersion = (char*) bstrHardware;
                        scanHeader.temperature = pStat->GetTemperature();
                        scanHeader.relativeHumidity = pStat->GetHumidity();
                        scanHeader.atmosphericPressure = pStat->GetAirPressure();
                }
///////////////////////////////////////////////////////////////
SETTING UP PointRecord Fields
Setup Points
                scanHeader.pointFields.cartesianInvalidStateField = true;
                int8_t * isInvalidData = new int8_t[nRow];
                scanHeader.pointFields.cartesianXField = true;
                double * xData = new double[nRow];
                scanHeader.pointFields.cartesianYField = true;
                double * yData = new double[nRow];
                scanHeader.pointFields.cartesianZField = true;
                double * zData = new double[nRow];
                scanHeader.pointFields.pointRangeScaledInteger = DATA_SCALE_FACTOR;
                scanHeader.pointFields.pointRangeMinimum = ((double)-E57_INT32_MAX) / DATA_SCALE_FACTOR;
                scanHeader.pointFields.pointRangeMaximum = ((double) E57_INT32_MAX) / DATA_SCALE_FACTOR;
Setup Color
                uint16_t * redData = NULL;
                uint16_t * greenData = NULL;
                uint16_t * blueData = NULL;
                if(exportColor)
                {
                        scanHeader.pointFields.colorRedField = true;
                        redData = new uint16_t[nRow];
                        scanHeader.pointFields.colorGreenField = true;
                        greenData = new uint16_t[nRow];
                        scanHeader.pointFields.colorBlueField = true;
                        blueData = new uint16_t[nRow];
                        scanheader.colorLimits.colorRedMinimum = e57::E57_UINT8_MIN;
                        scanheader.colorLimits.colorRedMaximum = e57::E57_UINT8_MAX;
                        scanheader.colorLimits.colorGreenMinimum = e57::E57_UINT8_MIN;
                        scanheader.colorLimits.colorGreenMaximum = e57::E57_UINT8_MAX;
                        scanheader.colorLimits.colorBlueMinimum = e57::E57_UINT8_MIN;
                        scanheader.colorLimits.colorBlueMaximum = e57::E57_UINT8_MAX;
                }
Setup Intensity
                double * intData = NULL;
                if(exportIntensity)
                {
                        scanHeader.pointFields.intensityField = true;
                        intData = new double[nRow];
                        header.intensityLimits.intensityMaximum = 1.;
                        headerintensityLimits.intensityMinimum = 0.;
                        header.pointFields.intensityScaledInteger = 0.;         //0. uses FloatNode, -1. uses IntegerNode, >0. uses ScaledIntegerNode
                }
Write out a new scan header and receive back the index
int scanIndex = eWriter.NewData3D(scanHeader);
Setup the data buffers
                e57::CompressedVectorWriter dataWriter = eWriter.SetUpData3DPointsData(
                                scanIndex,                      //!< data block index given by the NewData3D
                                nRow,                           //!< size of each of the buffers given
                                xData,                          //!< pointer to a buffer with the x data
                                yData,                          //!< pointer to a buffer with the y data
                                zData,                          //!< pointer to a buffer with the z data
                                isInvalidData,          //!< pointer to a buffer with the valid indication
                                intData,                        //!< pointer to a buffer with the lidar return intesity
                                NULL,
                                redData,                        //!< pointer to a buffer with the color red data
                                greenData,                      //!< pointer to a buffer with the color green data
                                blueData,                       //!< pointer to a buffer with the color blue data
                                NULL
                                );
/////////////////////////////////////////////////////////////// WRITING SCAN DATA
                vector<int64_t> idElementValue;
                vector<int64_t> startPointIndex;
                vector<int64_t> pointCount;
                int group = 0;
                int startPoint = 0;
Access the point data
                for(long j = 0; j < nColumn; j++)
                {
                        int count = 0;
                        for(long i = 0; i < nRow; i++)
                        {
Get the invalid status
isInvalidData[count] = (pScan->GetStatus(i,j) & INVALID) ? 2 : 0;
Get the point
                                ISI::Point point = pScan->GetPoint(i, j);
                                xData[count] = point.x();
                                yData[count] = point.y();
                                zData[count] = point.z();
Get the intensity 0. to 1. range
                                if(exportIntensity)
                                        intData[count] = pScan->GetIntensity(i, j);
Get the color
                                if(exportColor)
                                {
                                        uint8_t red = 0;
                                        uint8_t green = 0;
                                        uint8_t blue = 0;
                                        pScan->GetColor(i, j, &red, &green, &blue);
                                        redData[count] = (uint8_t) red;
                                        greenData[count] = (uint8_t) green;
                                        blueData[count] = (uint8_t) blue;
                                }
                                count++;
                        }
Write out the buffers
dataWriter.write(count);
Collect the group information
                        idElementValue.push_back((int64_t) j);
                        startPointIndex.push_back((int64_t) startPoint);
                        pointCount.push_back((int64_t) count);
                        group++;
                        startPoint += count;
                }
Finish the scan data write
dataWriter.close();
Write out the group information
                eWriter.WriteData3DGroupsData(scanIndex, group,
                        (int64_t*) &idElementValue[0],
                        (int64_t*) &startPointIndex[0],
                        (int64_t*) &pointCount[0]);
Clean up
                if(isInvalidData) delete isInvalidData;
                if(xData) delete xData;
                if(yData) delete yData;
                if(zData) delete zData;
                if(intData) delete intData;
                if(redData) delete redData;
                if(greenData) delete greenData;
                if(blueData) delete blueData;
///////////////////////////////////////////////////////////// SETTING UP SCAN IMAGE2D
e57::Image2D imageHeader;
Setup the Name and Description
                imageHeader.name = (char*) bstrName;
                imageHeader.description = (char*) bstrDesc;
Setup the GUID
                imageHeader.guid = (char*) bstrImageGuid;
                imageHeader.associatedData3DGuid = (char*) bstrScanGuid;
Setup the DateTime
imageHeader.acquisitionDateTime.SetCurrentGPSTime() //set current time.
Setup camera information
                imageHeader.sensorSerialNumber = (char*) bstrSerial;
                imageHeader.sensorVendor = (char*) bstrVendor;
                imageHeader.sensorModel = (char*) bstrModel;
Setup image orientation
                imageHeader.pose.rotation.w = rotation.w();
                imageHeader.pose.rotation.x = rotation.x();
                imageHeader.pose.rotation.y = rotation.y();
                imageHeader.pose.rotation.z = rotation.z();
                imageHeader.pose.translation.x = translation.x();
                imageHeader.pose.translation.y = translation.y();
                imageHeader.pose.translation.z = translation.z();
Setup image size
                imageHeader.sphericalRepresentation.imageHeight = imageHeight;
                imageHeader.sphericalRepresentation.imageWidth = imageWidth;
                imageHeader.sphericalRepresentation.pixelHeight = pixelHeight;
                imageHeader.sphericalRepresentation.pixelWidth = pixelWidth;
Open jpeg file
                CFile jpegFile;
                CFileException fileError;
                jpegFile.Open(imagePath, CFile::modeRead | CFile::typeBinary, &fileError);
                ULONGLONG dwLength = jpegFile.GetLength();
imageHeader.sphericalRepresentation.jpegImageSize = dwLength; //Real Size before newing image header
Write the image header
int imageIndex = eWriter.NewImage2D(header);
Access the jpeg image data
                void * pBuffer = new char[dwLength];
                jpegFile.SeekToBegin();
                jpegFile.Read(pBuffer,dwLength);
Write the jpeg data
                eWriter.WriteImage2DData(imageIndex, e57::E57_JPEG_IMAGE, e57::E57_SPHERICAL,
                                        pBuffer,0,dwLength);
Finish the E57 file
eWriter.Close();
///////////////////////////////////////////////////////////////////// CATCH THE ERRORS
        } catch(E57Exception& ex) {
                ex.report(__FILE__, __LINE__, __FUNCTION__);
        } catch (std::exception& ex) {
                cerr << "Got an std::exception, what=" << ex.what() << endl;
        } catch (...) {
                cerr << "Got an unknown exception" << endl;
        }
 1.8.2