c# free pdf viewer component : Adding a page to a pdf in reader control software system azure windows wpf console ReadingAndWritingImageFiles2-part838

out.writeTiles (0, out.numXTiles (xLevel) - 1,
0, out.numYTiles (yLevel) – 1,
xLevel,
yLevel);
}
}
}
As for 
ONE_LEVEL
and 
MIPMAP_LEVELS
files, the frame buffer doesn't have to be large enough to hold a 
whole level.  Any frame buffer big enough to hold at least a single tile will work.
Reading a Tiled RGBA Image File
Reading a tiled RGBA image file is done similarly to writing one:
void
readTiledRgba1 (const char fileName[],
Array2D<Rgba> &pixels,
int &width,
int &height)
{
TiledRgbaInputFile in (fileName);
Box2i dw = in.dataWindow();
width  = dw.max.x - dw.min.x + 1;
height = dw.max.y - dw.min.y + 1;
int dx = dw.min.x;
int dy = dw.min.y;
pixels.resizeErase (height, width);
in.setFrameBuffer (&pixels[-dy][-dx], 1, width);
in.readTiles (0, in.numXTiles() - 1, 0, in.numYTiles() - 1);
}
First we need to create a 
TiledRgbaInputFile
object for the given file name.  We then retrieve 
information about the data window in order to create an appropriately sized frame buffer, in this case large 
enough to hold the whole image at level 
(0,0)
.  After we set the frame buffer, we read the tiles from the file.
This example only reads the highest-resolution level of the image.  It can be extended to read all levels, for 
multi-resolution images, by also iterating over all levels within the image, analogous to the examples in 
Writing a Tiled RGBA Image File with Mipmap Levels, on page 18, and Writing a Tiled RGBA Image File
with Ripmap Levels, on page 20.
Using the General Interface for Tiled Files
Writing a Tiled Image File
This example is a variation of the one in Writing an Image File, on page 10.  We are writing a 
ONE_LEVEL 
image file with two channels, G, and Z, of type 
HALF
, and 
FLOAT
respectively, but here the file is tiled 
instead of scan line based:
void
writeTiled1 (const char fileName[],
Array2D<GZ> &pixels,
int width, int height,
int tileWidth, int tileHeight)
21
Adding a page to a pdf in reader - insert pages into PDF file in C#.net, ASP.NET, MVC, Ajax, WinForms, WPF
Guide C# Users to Insert (Empty) PDF Page or Pages from a Supported File Format
add page number to pdf online; adding page numbers to pdf in preview
Adding a page to a pdf in reader - VB.NET PDF Page Insert Library: insert pages into PDF file in vb.net, ASP.NET, MVC, Ajax, WinForms, WPF
Easy to Use VB.NET APIs to Add a New Blank Page to PDF Document
add page to existing pdf file; adding pages to a pdf document
{
Header header (width, height);                                          // 1
header.channels().insert ("G", Channel (HALF));                         // 2
header.channels().insert ("Z", Channel (FLOAT));                        // 3
header.setTileDescription
(TileDescription (tileWidth, tileHeight, ONE_LEVEL));               // 4
TiledOutputFile out (fileName, header);                                 // 5
FrameBuffer frameBuffer;                                                // 6
frameBuffer.insert ("G",                                     // name    // 7
Slice (HALF,                             // type    // 8
(char *) &pixels[0][0].g,         // base    // 9
sizeof (pixels[0][0]) * 1,       // xStride // 10
sizeof (pixels[0][0]) * width)); // yStride // 11
frameBuffer.insert ("Z",                                     // name    // 12
Slice (FLOAT,                            // type    // 13
(char *) &pixels[0][0].z,         // base    // 14
sizeof (pixels[0][0]) * 1,       // xStride // 15
sizeof (pixels[0][0]) * width)); // yStride // 16
out.setFrameBuffer (frameBuffer);                                       // 17
out.writeTiles (0, out.numXTiles() - 1, 0, out.numYTiles() - 1);        // 18
}
As one would expect, the code here is very similar to the code in Writing an Image File on page 10.  The 
file's header is created in line 1, while lines 2 and 3 specify the names and types of the image channels that 
will be stored in the file.  An important addition is line 4, where we define the size of the tiles and the level 
mode.  In this example we use 
ONE_LEVEL
for simplicity.  Line 5 opens the file and writes the header.  Lines 
6 through 17 tell the 
TiledOutputFile
object the location and layout of the pixel data for each channel. 
Finally, line 18 stores the tiles in the file.
Reading a Tiled Image File
Reading a tiled file with the general interface is virtually identical to reading a scan line based file, as shown 
in Interleaving Image Channels in the Frame Buffer, on page 14; only the last three lines are different. 
Instead of reading all scan lines at once with a single function call, here we must iterate over all tiles we want 
to read.
void
readTiled1 (const char fileName[],
Array2D<GZ> &pixels,
int &width, int &height)
{
TiledInputFile in (fileName);
Box2i dw = in.header().dataWindow();
width  = dw.max.x - dw.min.x + 1;
height = dw.max.y - dw.min.y + 1;
int dx = dw.min.x;
int dy = dw.min.y;
pixels.resizeErase (height, width);
FrameBuffer frameBuffer;
22
VB.NET PDF File & Page Process Library SDK for vb.net, ASP.NET
page modifying page, you will find detailed guidance on creating, loading, merge and splitting PDF pages and Files, adding a page into PDF document, deleting
add page break to pdf; add a page to a pdf in reader
VB.NET PDF Library SDK to view, edit, convert, process PDF file
Perform annotation capabilities to mark, draw, and visualize objects on PDF document page. Capable of adding PDF file navigation features to your VB.NET program
adding page numbers in pdf file; add page to pdf reader
frameBuffer.insert ("G",
Slice (HALF,
(char *) &pixels[-dy][-dx].g,
sizeof (pixels[0][0]) * 1,
sizeof (pixels[0][0]) * width));
frameBuffer.insert ("Z",
Slice (FLOAT,
(char *) &pixels[-dy][-dx].z,
sizeof (pixels[0][0]) * 1,
sizeof (pixels[0][0]) * width));
in.setFrameBuffer (frameBuffer);
in.readTiles (0, in.numXTiles() - 1, 0, in.numYTiles() - 1);
}
In this example we assume that the file we want to read contains two channels, G and Z, of type 
HALF
and 
FLOAT
respectively.  If the file contains other channels, we ignore them.  We only read the highest-resolution 
level of the image.  If the input file contains more levels (
MIPMAP_LEVELS
or 
MIPMAP_LEVELS
), we can 
access the extra levels by calling a four-argument version of the 
readTile()
function:
in.readTile (tileX, tileY, levelX, levelY);
or by calling a six-argument version of 
readTiles()
:
in.readTiles (tileXMin, tileXMax, tileYMin, tileYMax, levelX, levelY);
Deep Data Files (New in 2.0)
Writing a Deep Scan Line File
This example creates an deep scan line file with two channels.  It demonstrates how to write a deep scan line 
file with two channels:
1. type 
FLOAT
, is called Z, and is used for storing sample depth, and
2. type 
HALF
, is called O and is used for storing sample opacity.
The size of the image is 
width
by 
height
pixels.
void writeDeepScanlineFile(const char filename[],
Box2i displayWindow,
Box2i dataWindow,
Array2D< float* > dataZ,
Array2D< half* > dataO,
Array2D< unsigned int > sampleCount)
{
int height = dataWindow.max.y - dataWindow.min.y + 1;
int width = dataWindow.max.x - dataWindow.min.x + 1;
Header header(displayWindow, dataWindow);
header.channels().insert("Z", Channel(FLOAT));
header.channels().insert("O", Channel(HALF));
header.setType(DEEPSCANLINE);
DeepScanLineOutputFile file(filename, header);
DeepFrameBuffer frameBuffer;
23
C# PDF insert image Library: insert images into PDF in C#.net, ASP
digital photo, scanned signature or logo into PDF document page in C# solve this technical problem, we provide this C#.NET PDF image adding control, XDoc
add remove pages from pdf; add pages to pdf without acrobat
C# PDF insert text Library: insert text into PDF content in C#.net
text and plain text to PDF page using .NET XDoc.PDF component in C#.NET class. Supports adding text to PDF in preview without adobe reader installed in ASP.NET.
add page number to pdf document; add pages to pdf
frameBuffer.insertSampleCountSlice (Slice (UINT,
(char *) (&sampleCount[0][0]
- dataWindow.min.x
- dataWindow.min.y * width),
sizeof (unsigned int) * 1,           // xStride
sizeof (unsigned int) * width));     // yStride
frameBuffer.insert ("dataZ",
DeepSlice (FLOAT,
(char *) (&dataZ[0][0]
- dataWindow.min.x
- dataWindow.min.y * width),
sizeof (float *) * 1,                // xStride for pointer array
sizeof (float *) * width,            // yStride for pointer array
sizeof (float) * 1));                // stride for Z data sample
frameBuffer.insert ("dataO",
DeepSlice (HALF,
(char *) (&dataO[0][0]
- dataWindow.min.x
- dataWindow.min.y * width),
sizeof (half *) * 1,                // xStride for pointer array
sizeof (half *) * width,            // yStride for pointer array
sizeof (half) * 1));                // stride for O data sample
file.setFrameBuffer(frameBuffer);
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
sampleCount[i][j] = getPixelSampleCount(j, i);
dataZ[i][j] = new float[sampleCount[i][j]];
dataO[i][j] = new half[sampleCount[i][j]];
// Generate data for dataZ and dataO.
}
file.writePixels(1);
}
for (int i = 0; i < height; i++)
for (int j = 0; j < width; j++)
{
delete[] dataZ[i][j];
delete[] dataO[i][j];
}
}
The interface for deep scan line files is similar to scan line files.  We added two new classes to deal with deep 
data: 
DeepFrameBuffer
and 
DeepSlice
 
DeepFrameBuffer
only accepts 
DeepSlice
as its input, 
except that it accepts 
Slice
for sample count slice.  The first difference we see from the previous version is:
header.setType(DEEPSCANLINE);
where we set the type of the header to a predefine string 
DEEPSCANLINE
, then we insert a sample count slice 
using 
insertSampleCountSlice()
 After that, we insert a 
DeepSlice
with deep z data.  Notice that 
deep slices have three strides, one more than non-deep slices.  The first two strides are used for the pointers in 
the array.  Because the memory space for 
Array2D
is contiguous, we can get the strides easily.  The third 
stride is used for pixel samples.  Because the data type is float (and we are not interleaving), the stride should 
be 
sizeof (float)
 If we name the stride for deep data samples 
sampleStride
, then the memory 
address of the i-th sample of this channel in pixel (x, y) is
base +
x * xStride + 
y * yStride + 
i * sampleStride
24
C# PDF File & Page Process Library SDK for C#.net, ASP.NET, MVC
Provides you with examples for adding an (empty) page to a PDF and adding empty pages to a PDF from a supported file format, with customized options.
add blank page to pdf preview; add page number to pdf file
VB.NET PDF insert text library: insert text into PDF content in vb
Studio .NET PDF SDK library supports adding text content to Add text to certain position of PDF page in Visual Add text to PDF in preview without adobe reader
add contents page to pdf; add page pdf
Because we may not know the data until we are going to write it, the deep data file must support postponed 
initialization, as shown in the example code.  Another approach would be to prepare all the data first, and then 
write it all out at once.
Reading a Deep Scan Line File
An example of reading a deep scan line file created by previous code.
void readDeepScanlineFile(const char filename[],
Box2i& displayWindow,
Box2i& dataWindow,
Array2D< float* >& dataZ,
Array2D< half* >& dataO,
Array2D< unsigned int >& sampleCount)
{
DeepScanLineInputFile file(filename);
const Header& header = file.header();
dataWindow = header.dataWindow();
displayWindow = header.displayWindow();
int width = dataWindow.max.x - dataWindow.min.x + 1;
int height = dataWindow.max.y - dataWindow.min.y + 1;
sampleCount.resizeErase(height, width);
dataZ.resizeErase(height, width);
dataO.resizeErase(height, width);
DeepFrameBuffer frameBuffer;
frameBuffer.insertSampleCountSlice (Slice (UINT,
(char *) (&sampleCount[0][0]
- dataWindow.min.x
- dataWindow.min.y * width),
sizeof (unsigned int) * 1,          // xStride
sizeof (unsigned int) * width));    // yStride
frameBuffer.insert ("dataZ",
DeepSlice (FLOAT,
(char *) (&dataZ[0][0]
- dataWindow.min.x
- dataWindow.min.y * width),
sizeof (float *) * 1,             // xStride for pointer array
sizeof (float *) * width,         // yStride for pointer array
sizeof (float) * 1)); // stride for Z data sample
frameBuffer.insert ("dataO",
DeepSlice (HALF,
(char *) (&dataO[0][0]
- dataWindow.min.x
- dataWindow.min.y * width),
sizeof (half *) * 1,             // xStride for pointer array
sizeof (half *) * width,         // yStride for pointer array
sizeof (half) * 1));  // stride for O data sample
file.setFrameBuffer(frameBuffer);
file.readPixelSampleCounts(dataWindow.min.y, dataWindow.max.y);
for (int i = 0; i < height; i++)
for (int j = 0; j < width; j++)
{
dataZ[i][j] = new float[sampleCount[i][j]];
dataO[i][j] = new half[sampleCount[i][j]];
}
25
C# PDF Annotate Library: Draw, edit PDF annotation, markups in C#.
notes on adobe PDF file without adobe reader installed. Provide users with examples for adding text box to users to draw various annotation markups on PDF page.
adding page numbers to pdf files; add page to pdf online
VB.NET TIFF: Read, Edit & Process TIFF with VB.NET Image Document
at the page level, like TIFF page adding & deleting Viewers in VB.NET, TIFF Page Processing Within VB powerful & profession imaging controls, PDF document, image
add pdf pages to word document; adding page numbers to pdf documents
file.readPixels(dataWindow.min.y, dataWindow.max.y);
for (int i = 0; i < height; i++)
for (int j = 0; j < width; j++)
{
delete[] dataZ[i][j];
delete[] dataO[i][j];
}
}
The interface for deep scan line files is similar to scan line files.  The main the difference is we use the sample 
count slice and deep data slices.  To do this, we added a new method to read the sample count table from the 
file:
file.readPixelSampleCounts(dataWindow.min.y, dataWindow.max.y);
This method reads all pixel sample counts in the range 
[dataWindow.min.y, dataWindow.max.y]
, and 
stores the data to sample count slice in framebuffer.
ReadPixels()
supports for postponed memory allocation.
Writing a Deep Tiled File
This example creates an deep tiled file with two channels.  It demonstrates how to write a deep tiled file with 
two channels:
1. type 
FLOAT
, is called Z, and is used for storing sample depth, and
2. type 
HALF
, is called A and is used for storing sample opacity.
The size of the image is 
width
by 
height
pixels.
void writeDeepTiledFile(const char filename[],
Box2i displayWindow,
Box2i dataWindow,
int tileSizeX, int tileSizeY)
{
int height = dataWindow.max.y - dataWindow.min.y + 1;
int width = dataWindow.max.x - dataWindow.min.x + 1;
Header header(displayWindow, dataWindow);
header.channels().insert("Z", Channel(FLOAT));
header.channels().insert("A", Channel(HALF));
header.setType(DEEPTILE);
header.setTileDescription(
TileDescription(tileSizeX, tileSizeY, MIPMAP_LEVELS));
Array2D< unsigned int* > dataZ;
dataZ.resizeErase(height, width);
Array2D< unsigned int* > dataA;
dataO.resizeErase(height, width);
Array2D<unsigned int> sampleCount;
sampleCount.resizeErase(height, width);
DeepTiledOutputFile file(filename, header);
DeepFrameBuffer frameBuffer;
frameBuffer.insertSampleCountSlice (Slice (UINT,
(char *) (&sampleCount[0][0]
- dataWindow.min.x
- dataWindow.min.y * width),              
sizeof (unsigned int) * 1,          // xStride
sizeof (unsigned int) * width));    // yStride
26
frameBuffer.insert ("Z",
DeepSlice (FLOAT,
(char *) (&dataZ[0][0]
- dataWindow.min.x
- dataWindow.min.y * width),
sizeof (float *) * 1,            // xStride for pointer array
sizeof (float *) * width,        // yStride for pointer array
sizeof (float) * 1));            // stride for samples
frameBuffer.insert ("A",
DeepSlice (HALF,
(char *) (&dataO[0][0]
- dataWindow.min.x
- dataWindow.min.y * width),
sizeof (half *) * 1,             // xStride for pointer array
sizeof (half *) * width,         // yStride for pointer array
sizeof (half) * 1));             // stride for samples
file.setFrameBuffer(frameBuffer);
for (int l = 0; l < file.numLevels(); l++)
{
for (int j = 0; j < file.numYTiles(l); j++)
{
for (int i = 0; i < file.numXTiles(l); i++)
{
getSampleCountForTile(i, j, sampleCount);
getSampleDataForTile(i, j, dataZ, dataA);
file.writeTile(i, j, l);
}
}
}
}
Here, getSampleCountForTile is a user-supplied function that sets each item in sampleCount array to the 
correct sampleCount for each pixel in the tile, and getSampleDataForTile is a user-supplied function that set 
the pointers in dataZ and dataO arrays to point to the correct data
The interface for deep tiled files is similar to tiled files.  The differences are:
we set the type of the header to 
DEEPTILE
we use 
insertSampleCountSlice()
to set sample count slice, and 
we use 
DeepSlice
instead of 
Slice
to provide three strides needed by the library.
Also, we support postponed initialization.
Reading a Deep Tiled File
An example of reading a deep tiled file created by code explained in the Writing a Deep Tiled File section, 
on page 26.
void readDeepTiledFile(const char filename[],
Box2i& displayWindow,
Box2i& dataWindow,
Array2D< float* >& dataZ,
Array2D< half* >& dataA,
Array2D< unsigned int >& sampleCount)
{
DeepTiledInputFile file(filename);
int width = dataWindow.max.x - dataWindow.min.x + 1;
int height = dataWindow.max.y - dataWindow.min.y + 1;
27
sampleCount.resizeErase(height, width);
dataZ.resizeErase(height, width);
dataO.resizeErase(height, width);
DeepFrameBuffer frameBuffer;
frameBuffer.insertSampleCountSlice (Slice (UINT,
(char *) (&sampleCount[0][0]
- dataWindow.min.x
- dataWindow.min.y * width),
sizeof (unsigned int) * 1,          // xStride
sizeof (unsigned int) * width));    // yStride
frameBuffer.insert ("Z",
DeepSlice (FLOAT,
(char *) (&dataZ[0][0]
- dataWindow.min.x
- dataWindow.min.y * width),
sizeof (float *) * 1,          // xStride for pointer array
sizeof (float *) * width,      // yStride for pointer array
sizeof (float) * 1));          // stride for samples
frameBuffer.insert ("A",
DeepSlice (HALF,
(char *) (&dataA[0][0]
- dataWindow.min.x
- dataWindow.min.y * width),
sizeof (half *) * 1,           // xStride for pointer array
sizeof (half *) * width,       // yStride for pointer array
sizeof (half) * 1));           // stride for samples
file.setFrameBuffer(frameBuffer);
int numXTiles = file.numXTiles(0);
int numYTiles = file.numYTiles(0);
file.readPixelSampleCounts(0, numXTiles - 1, 0, numYTiles - 1);
for (int i = 0; i < height; i++)
for (int j = 0; j < width; j++)
{
dataZ[i][j] = new float[sampleCount[i][j]];
dataO[i][j] = new half[sampleCount[i][j]];
}
file.readTiles(0, numXTiles - 1, 0, numYTiles – 1);
// (after read data is processed, data must be freed:)
for (int i = 0; i < height; i++)
for (int j = 0; j < width; j++)
{
delete[] dataZ[i][j];
delete[] dataA[i][j];
}
}
This code demonstrates how to read the first level of a deep tiled file created by code explained in the Writing
a Deep Tiled File section, on page 26 The interface for deep tiled files is similar to tiled files.  The 
differences are:
we use 
insertSampleCountSlice()
to set sample count slice
we use 
DeepSlice
instead of 
Slice
to provide three strides needed by the library, and
we use 
readPixelSampleCounts()
to read in pixel sample counts into array.
Also we support postponed memory allocation.
28
In this example, entries in dataZ and dataA have been allocated by the 'new' calls must be deleted after use.
Threads
Library Thread-Safety
The IlmImf library is thread-safe.  In a multithreaded application program, multiple threads can concurrently 
read and write distinct OpenEXR files.  In addition, accesses to a single shared file by multiple application 
threads are automatically serialized.  In other words, each thread can independently create, use and destroy its 
own input and output file objects.  Multiple threads can also share a single input or output file.  In the latter 
case the IlmImf library uses mutual exclusion to ensure that only one thread at a time can access the shared 
file.
Multithreaded I/O
The IlmImf library supports multithreaded file input and output where the library creates its own worker 
threads that are independent of the application program's threads.  When an application thread calls 
readPixels()
readTiles()
writePixels()
or 
writeTiles()
to read or write multiple scan lines or 
tiles at once, the library's worker threads process the tiles or scanlines in parallel.
During startup,  the  application  program must  enable  multithreading  by  calling  function 
setGlobalThreadCount()
.  This tells the IlmImf library how many worker threads it should create.  (As a 
special case, setting the number of worker threads to zero reverts to single-threaded operation; reading and 
writing image files happens entirely in the application thread that calls the IlmImf library.)
The application program should read or write as many scan lines or tiles as possible in each call to 
readPixels()
readTiles()
writePixels()
or 
writeTiles()
.  This allows the library to break up 
the work into chunks that can be processed in parallel.  Ideally the application reads or writes the entire image 
using a single read or write call.  If the application reads or writes the image one scan line or tile at a time, the 
library reverts to single-threaded file I/O.
The following function writes an RGBA file using four concurrent worker threads:
void
writeRgbaMT (const char fileName[],
const Rgba *pixels,
int width,
int height)
{
setGlobalThreadCount (4);
RgbaOutputFile file (fileName, width, height, WRITE_RGBA);
file.setFrameBuffer (pixels, 1, width);
file.writePixels (height);
}
Except for the call to 
setGlobalThreadCount()
, function 
writeRgbaMT()
is identical to function 
writeRgba1()
in Writing an RGBA Image File, on page 4, but on a computer with multiple processors 
writeRgbaMT()
writes files significantly faster than 
writeRgba1()
.
Multithreaded I/O, Multithreaded Application Program
Function 
setGlobalThreadCount()
creates a global pool of worker threads inside the IlmImf library.  If 
an application program has multiple threads, and those threads read or write several OpenEXR files at the 
same time, then the worker threads must be shared among the application threads.  By default each file will 
attempt to use the entire worker thread pool for itself.  If two files are read or written simultaneously by two 
application threads, then it is possible that all worker threads perform I/O on behalf of one of the files, while 
I/O for the other file is stalled.
29
In order to avoid this situation, the constructors for input and output file objects take an optional 
numThreads
argument.  This gives the application program more control over how many threads will be 
kept busy reading or writing a particular file.
For example, we may have an application program that runs on a four-processor computer.  The program has 
one thread that reads files and another one that writes files.  We want to keep all four processors busy, and we 
want to split the processors evenly between input and output.  Before creating the input and output threads, 
the application instructs the IlmImf library to create four worker threads:
// main, before application threads are created:
setGlobalThreadCount (4);
In the input and output threads, input and output files are opened with 
numThreads
set to 2:
// application's input thread
InputFile in (fileName, 2);
...
// application's output thread
OutputFile out (fileName, header, 2);
...
This ensures that file input and output in the application's two threads can proceed concurrently, without one 
thread stalling the other's I/O.
An alternative approach for thread management of multithreaded applications is provided for deep scanline 
input files. Rather than calling setFrameBuffer(), the host application may call rawPixelData() to 
load a chunk of scanlines into a host-application managed memory store, then pass a DeepFrameBuffer object 
and the raw data to readPixelSampleCounts() and readPixels(). Only the call to rawPixelData 
blocks; decompressing the underlying data and copying it to the framebuffer will happen on the host 
application's threads independently. This strategy is generally less efficient than reading multiple scanlines at 
the same time and allowing OpenEXR's thread management to decode the file, but may prove effective when 
the host application has many threads available, cannot avoid accessing scanlines in a random order and 
wishes to avoid caching an entire uncompressed image. For more details, refer to the inline comments  in 
ImfDeepScanLineInputFile.h 
Low-Level I/O
Custom Low-Level File I/O
In all of the previous file reading and writing examples, we were given a file name, and we relied on the 
constructors for our input file or output file objects to open the file.  In some contexts, for example, in a 
plugin for an existing application program, we may have to read from or write to a file that has already been 
opened.  The representation of the open file as a C or C++ data type depends on the application program and 
on the operating system.
At its lowest level, the IlmImf library performs file I/O via objects of type 
IStream
and 
OStream
IStream 
and 
OStream
are abstract base classes.  The IlmImf library contains two derived classes, 
StdIFStream
and 
StdOFStream
, that implement reading from 
std::ifstream
and writing to 
std::ofstream
objects.  An 
application program can implement alternative file I/O mechanisms by deriving its own classes from 
Istream
and 
Ostream
 This way, OpenEXR images can be stored in arbitrary file-like objects, as long as it 
is possible to support read, write, seek and tell operations with semantics similar to the corresponding 
std::ifstream
and 
std::ofstream
methods.
30
Documents you may be interested
Documents you may be interested