Pajdeg  0.2.2
Pajdeg
Files | Data Structures | Macros | Typedefs | Functions
PDStreamFilter

The stream filter interface. More...

Files

file  PDStreamFilter.h
 

Data Structures

struct  PDStreamFilter
 

Macros

#define PDStreamFilterPrepare(f, buf_in, len_in, buf_out, len_out)
 

Typedefs

typedef struct PDStreamFilterPDStreamFilterRef
 
typedef PDInteger(* PDStreamFilterFunc) (PDStreamFilterRef filter)
 
typedef PDStreamFilterRef(* PDStreamFilterPrcs) (PDStreamFilterRef filter)
 
typedef PDStreamFilterRef(* PDStreamDualFilterConstr) (PDBool inputEnd, PDDictionaryRef options)
 

Functions

PDStreamFilterRef PDStreamFilterCreate (PDStreamFilterFunc init, PDStreamFilterFunc done, PDStreamFilterFunc begin, PDStreamFilterFunc proceed, PDStreamFilterPrcs createInversion, PDDictionaryRef options)
 
void PDStreamFilterRegisterDualFilter (const char *name, PDStreamDualFilterConstr constr)
 
PDStreamFilterRef PDStreamFilterObtain (const char *name, PDBool inputEnd, PDDictionaryRef options)
 
void PDStreamFilterAppendFilter (PDStreamFilterRef filter, PDStreamFilterRef next)
 
PDBool PDStreamFilterInit (PDStreamFilterRef filter)
 
PDBool PDStreamFilterDone (PDStreamFilterRef filter)
 
PDInteger PDStreamFilterBegin (PDStreamFilterRef filter)
 
PDInteger PDStreamFilterProceed (PDStreamFilterRef filter)
 
PDBool PDStreamFilterApply (PDStreamFilterRef filter, unsigned char *src, unsigned char **dstPtr, PDInteger len, PDInteger *newlenPtr, PDInteger *allocatedlenPtr)
 
PDStreamFilterRef PDStreamFilterCreateInversionForFilter (PDStreamFilterRef filter)
 
PDStreamFilterRef PDStreamFilterAlloc (void)
 

Detailed Description

The stream filter interface.

Stream filters are used to read or write content that is filtered in some way, such as FlateDecode streams (compressed).

Globally registered filters

Filters can be registered globally using PDStreamFilterRegisterDualFilter() and be accessed from anywhere via PDStreamFilterObtain().

By default, if PD_SUPPORT_ZLIB is defined, the first call to pd_pdf_implementation_use() will permanently register two filters, "FlateDecode" and "Predictor".

Registered filters can be overridden by registering a filter with the same name as an already existing one – the most recently registered filter always takes precedence.

Chaining filters together

Filters can be chained together by linking them to each other via the nextFilter property.

Some filters will hook child filters up automatically if they are passed options that they recognize.

The FlateDecode (compression) filter will add a Predictor filter to itself, if initialized with options that include the key "Predictor".

This goes both ways:

Chained filters are transparent to the caller, in the sense that the first filter in the chain holds the output buffer and capacity for the whole filter chain.

Note
Chained filters are an extension mechanism enabled via PDStreamFilterBegin() and PDStreamFilterProceed(). Calling a filter's begin or proceed function pointers directly will only execute that filter.

Dual filters and inversion

Currently all filters are, but need not be, dual. This means all filters come in pairs complementing each other, so that if data is passed into one and through the other, presuming the options are identical for both, the data remains unmodified.

FlateDecode has the compression (inflate) and decompression (deflate) filters, and Predictor has the predict and unpredict filters.

A non-dual filter must return NULL for the unsupported method (input or output) in the dual filter construction callback. There is no such thing as a non dual filter construction callback.

All filters are, but again, need not be, inversible. This means the filter has the means to create a new filter that is its inverse, including the correct filter options.

Chained filters can also be inversed, if all filters in the chain can be inversed. A PNG_UP (6 col) predictor with a FlateDecode compressor attached to it is laid out as such

encode = [filter: Predictor-Predictor <Strategy PNG_UP, Columns 6>]
encode.nextFilter = [filter: FlateDecode-Compression]

Setting decode to the results of PDStreamFilterCreateInversionForFilter() for encode produces

decode = [filter: FlateDecode-Decompression]
decode.nextFilter = [filter: Predictor-Unpredictor <Strategy PNG_UP, Columns 6>]

Passing plaintext data into encode would produce predictor-filtered compressed data, and passing that data into decode gives back the original plaintext data.

Using the inversion mechanism is strongly recommended when modifying filtered content via Pajdeg, rather than setting up two filter chains manually, as the inverter code evolves with the filters (while manual code stays the same).

Note
Chained filter inversion is an extension mechanism enabled via PDStreamFilterCreateInversionForFilter(). Calling a filter's createInversion function directly will produce an inversion for that filter only, excluding its nextFilter chain.

Data Structure Documentation

struct PDStreamFilter

The stream filter struct.

Data Fields

PDBool initialized
 Determines if filter was set up or not.
 
PDBool compatible
 If false after initialization, the filter initialized fine but encountered compatibility issues that could potentially cause problems.
 
PDBool needsInput
 Whether the filter needs data. If true, its input buffer must not be modified.
 
PDBool hasInput
 Whether the filter has pending input that, for capacity reasons, has not been added to the buffer yet.
 
PDBool finished
 Whether the filter is finished.
 
PDBool failing
 Whether the filter is failing to handle its input.
 
PDDictionaryRef options
 Filter options.
 
void * data
 User info object.
 
unsigned char * bufIn
 Input buffer.
 
unsigned char * bufOut
 Output buffer.
 
PDInteger bufInAvailable
 Available data.
 
PDInteger bufOutCapacity
 Output buffer capacity.
 
PDStreamFilterFunc init
 Initialization function. Called once before first use.
 
PDStreamFilterFunc done
 Deinitialization function. Called once after last use.
 
PDStreamFilterFunc begin
 Processing function. Called any number of times, at most once per new input buffer.
 
PDStreamFilterFunc proceed
 Proceed function. Called any number of times to request more output from last begin call.
 
PDStreamFilterPrcs createInversion
 Inversion function. Returns, if possible, a filter chain that reverts the current filter.
 
PDStreamFilterRef nextFilter
 The next filter that should receive the output end of this filter as its input, or NULL if no such requirement exists.
 
float growthHint
 The growth hint is an indicator for how the filter expects the size of its resulting data to be relative to the unfiltered data.
 
unsigned char * bufOutOwned
 Internal output buffer, that will be freed on destruction. This is used internally for chained filters.
 
PDInteger bufOutOwnedCapacity
 Capacity of internal output buffer.
 

Macro Definition Documentation

#define PDStreamFilterPrepare (   f,
  buf_in,
  len_in,
  buf_out,
  len_out 
)
Value:
do { \
f->bufIn = (unsigned char *)buf_in; \
f->bufOut = (unsigned char *)buf_out; \
f->bufInAvailable = len_in; \
f->bufOutCapacity = len_out; \
} while (0)

Convenience macro for setting buffers and sizes.

Typedef Documentation

typedef PDStreamFilterRef(* PDStreamDualFilterConstr) (PDBool inputEnd, PDDictionaryRef options)

Dual filter construction signature.

If inputEnd is set, the reader variant is returned, otherwise the writer variant is returned.

typedef PDInteger(* PDStreamFilterFunc) (PDStreamFilterRef filter)

Filter function signature.

typedef PDStreamFilterRef(* PDStreamFilterPrcs) (PDStreamFilterRef filter)

Filter processing signature. Used for inverting filters currently.

The stream filter type.

Function Documentation

PDStreamFilterRef PDStreamFilterAlloc ( void  )

Convert a PDScanner dictionary stack into a stream filter options stack.

Note
The original stack remains untouched.
Parameters
dictStackThe dictionary stack to convert
Returns
New allocated stack suited for stream filter options. Allocate an uninitialized, non-zeroed stream filter object.
Note
This is used by filters to create other filters, and should not be called outside of filter contexts.
void PDStreamFilterAppendFilter ( PDStreamFilterRef  filter,
PDStreamFilterRef  next 
)

Append a filter to the filter, causing a chain.

The filter is appended to the end (i.e. it will run at the very last), if there are more than one filters connected already.

Parameters
filterThe pre-filter.
nextThe filter to append.
PDBool PDStreamFilterApply ( PDStreamFilterRef  filter,
unsigned char *  src,
unsigned char **  dstPtr,
PDInteger  len,
PDInteger newlenPtr,
PDInteger allocatedlenPtr 
)

Apply a filter to the given buffer, creating a new buffer and size. This is a convenience method for applying a filter (chain) to some data and getting a newly allocated buffer containing the results back, along with the result size.

Parameters
filterThe filter to apply
srcThe source buffer
dstPtrThe destination buffer pointer
lenThe length of the source buffer content
newlenPtrThe filtered content length pointer
allocatedlenPtrThe resulting allocation size of the destination buffer (optional, use NULL if unneeded)
Returns
true on success, false on failure.
PDInteger PDStreamFilterBegin ( PDStreamFilterRef  filter)

Begin processing, meaning that the filter should take its input buffer as new content.

Warning
Performing multiple separate filtering operations is not done by calling PDStreamFilterBegin() at the start of each new operation. The purpose of PDStreamFilterBegin() is to tell the filter that new or additional data for one consecutive operation has been put into its input buffer. To reuse a filter, it must be deinitialized via PDStreamFilterDone(), and then reinitialized via PDStreamFilterInit().
Parameters
filterThe filter
Returns
Number of bytes produced
PDStreamFilterRef PDStreamFilterCreate ( PDStreamFilterFunc  init,
PDStreamFilterFunc  done,
PDStreamFilterFunc  begin,
PDStreamFilterFunc  proceed,
PDStreamFilterPrcs  createInversion,
PDDictionaryRef  options 
)

Set up a stream filter with given callbacks.

Parameters
initThe initializer. Returns 0 on failure, some other value on success.
doneThe deinitializer. Returns 0 on failure, some other vaule on success.
beginThe begin function; called once when new data is put into bufIn. Returns # of bytes stored into output buffer.
proceedThe proceed function; called repeatedly after a begin call was made, until the filter returns 0 lengths. Returns # of bytes stored into output buffer.
createInversionThe inversion function; calling this will produce a filter that inverts this filter.
optionsOptions passed to the filter, in the form of a dictionary.
See also
PDStreamFilterGenerateOptionsFromDictionaryStack
PDStreamFilterRef PDStreamFilterCreateInversionForFilter ( PDStreamFilterRef  filter)

Create the inversion of the given filter, so that invert(filter(data)) == data

Parameters
filterThe filter to invert.
Returns
Inversion filter, or NULL if the filter or any of its chained filters is unable to invert itself.
PDBool PDStreamFilterDone ( PDStreamFilterRef  filter)

Deinitialize a filter.

Parameters
filterThe filter.
PDBool PDStreamFilterInit ( PDStreamFilterRef  filter)

Initialize a filter.

Parameters
filterThe filter.
PDStreamFilterRef PDStreamFilterObtain ( const char *  name,
PDBool  inputEnd,
PDDictionaryRef  options 
)

Obtain a filter for given name and type, where the type is a boolean value for whether the filter should be a reader (i.e. decompress) or writer (i.e. compress).

Parameters
nameThe name of the filter.
inputEndWhether the input end or output end should be returned. The input end is the reader part (decoder) and the output end is the writer part (encoder).
optionsOptions passed to the filter, in the form of a simplified pd_stack dictionary (with keys and values and no complex objects). A scanner-produced pd_stack dictionary can be converted into a stream filter options dictionary via PDStreamFilterGenerateOptionsFromDictionaryStack().
Returns
A created PDStreamFilterRef or NULL if no match.
See also
PDStreamFilterGenerateOptionsFromDictionaryStack
PDInteger PDStreamFilterProceed ( PDStreamFilterRef  filter)

Proceed with a filter, meaning that it should continue filtering its input, which must not have been altered. This is called if a filter's output hits the output buffer capacity when processing its current input.

Parameters
filterThe filter
Returns
Number of bytes produced
void PDStreamFilterRegisterDualFilter ( const char *  name,
PDStreamDualFilterConstr  constr 
)

Register a dual filter with a given name.

Parameters
nameThe name of the filter
constrThe dual filter construction function.