A QisMLib extension to correct, annotate and rasterize GDSII designs in real-time
QisMRTCR ExtensionQisMRTCR C++ API (qismrtcr.h)QisMRTCRFlagsQisMAnnotationSpecQisMRTCRAnnotationsVersion ControlGet_error_msgGet_error_conditionAdd_annotationAdd_box_annotationAdd_from_fileGet_item_countWrite_to_fileResetCloneQisMRTCRCorrectionsVersion ControlGet_error_msgGet_error_conditionSet_toleranceGet_toleranceAdd_domainAdd_from_fileGet_domain_countGet_domainWrite_to_fileResetCloneQisMRTCROptsVersion ControlSet_layersGet_layersSet_load_from_diskGet_load_from_diskSet_keep_working_filesGet_keep_working_filesResetCloneQisMRTCRasterizerQisMRTCRImageArgsenum TypeVersion ControlSet_argGet_argResetCopyCloneQisMRTCRJobVersion ControlGet_error_msgGet_error_conditionFile_dbGet_directoryDPI_to_pixelsizePixelsize_to_DPICreate_rasterizerDestroy_rasterizerGet_raster_imageQisMRTCRJobV2Create_corrx_rasterizerQisMRTCRJobV3Get_raster_image_optsQisMRTCRJobV4RTCR_apiRTCR_api_constQisMRTCRVersion ControlGet_error_msgGet_error_conditionCreate_objectDestroy_objectSetup_jobEnd_jobQisMRTCRV2Rasterizer_coreQisMRTCR Error Conditions QisMRTCR commandsrtcr.create_optsrtcr.destroy_optsrtcr.create_correctionsrtcr.destroy_correctionsrtcr.create_annotationsrtcrannotations.addrtcr.destroy_annotationsrtcr.setup_jobrtcr.end_jobrtcrjob.create_rasterizerrtcrjob.get_raster_imagertcrjob.destroy_rasterizerQisMRTCR Licensing (API)QisMRTCR Licensing (SCRIPT)QisMRTCR Version Historyqismrtcr dll v1.6 04-2023qismrtcr dll v1.5 05-2022qismrtcr dll v1.4, v1.4.1 05-2020qismrtcr dll v1.3 12-2019qismrtcr dll v1.2 10-2019qismrtcr dll v1.1 08-2019qismrtcr dll v1.0 07-2019
QisMRTCRFlagsRepresents various QisMRTCR flags
struct QisMRTCRFlags{ enum Shift_type { STF_NONE=0 /* no shifting */ ,STF_INS_WHITE=1 /* insert a white row/column at the specified locations */ ,STF_INS_BLACK=2 /* insert a black row/column at the specified locations */ ,STF_REMOVE=3 /* remove a row/column at the specified locations */ };};QisMAnnotationSpecRepresents settings for a single annotation item
angle_dg : rotation in degrees
scale : reserved for future use. the height or box of the annotation can be adjusted to have the same effect
margin_mm : distance of the characters from the bounding box/frame (* in MM *)
inverse : (if true) text is etched from the box
frame : (if true) text is surrounded by a border
backwards : (if true) characters read from right-to-left
xstruct QisMAnnotationSpec{ double angle_dg, scale, margin_mm; bool inverse, frame, backwards;
QisMAnnotationSpec(): angle_dg(0.0), scale(1.0), margin_mm(0.0), inverse(false), frame(false), backwards(false) {} QisMAnnotationSpec& operator=(const QisMAnnotationSpec& o) { angle_dg = o.angle_dg; scale = o.scale; margin_mm = o.margin_mm; inverse = o.inverse; frame = o.frame; backwards = o.backwards; return *this; }};QisMRTCRAnnotationsRepresents a specification for applying annotations
xxxxxxxxxxclass QisMRTCRAnnotations { ... };Cast this class pointer to any other version (base/derived)
The version number is embedded in the class name in form of a suffix V
Get the latest version number supported by this implementation
xxxxxxxxxxvirtual const char* QisMRTCRAnnotations_name(const int version) const = 0;virtual void* QisMRTCRAnnotations_cast(const int version) = 0;virtual const void* QisMRTCRAnnotations_cast(const int version) const = 0;virtual int QisMRTCRAnnotations_latest_version() const = 0;Get information about an error
ecode : non-zero value indicating an error
Get_error_msg() returns the error details
Get_error_condition() returns the error tag to identify the error See qismrtcr.error.h
xxxxxxxxxxvirtual const char* Get_error_msg(const int ecode) const = 0;virtual const char* Get_error_condition(const int code) const = 0;Add one annotation bounded by height
text : text string (can contain '\n')
x, y : insertion point (in file units)
height : height of the text (in file units)
spec : other options (null implies defaults)
units_m : file units in meters
grid : smallest distance (in file units)
xxxxxxxxxxvirtual int Add_annotation( const char* text, const double x, const double y, const double height, const double units_m, const double grid = 0.001, const QisMAnnotationSpec* spec = 0 ) = 0;Add one annotation bounded by a box
text : text string (can contain '\n')
minx, miny, maxx, maxy : bounding box (in file units)
spec : other options (null implies defaults)
grid : file grid
xxxxxxxxxxvirtual int Add_box_annotation( const char* text, const double minx, const double miny, const double maxx, const double maxy, const double units_m, const double grid = 0.001, const QisMAnnotationSpec* spec = 0 ) = 0;Import annotations from a text file
file_path : path of the file to read
Return: 0 (success), Otherwise call Get_error_msg(), Get_error_condition() for error details
See Write_to_file for syntax of the text file
xxxxxxxxxxvirtual int Add_from_file(const char* file_path) = 0;Get number of annotations (0 implies no annotations)
xxxxxxxxxxvirtual int Get_item_count() const = 0;Write annotations to a text file
file_path : path where is text file will be created
Return: 0 (success), Otherwise call Get_error_msg(), Get_error_condition() for error details
Syntax of the text file : One or more annotations. Each one :-
xxxxxxxxxxB_TEXT_ANNOTATION# Use a BOX to specify text position :BOX ${MINX_MM} ${MINY_MM} ${MAXX_MM} ${MAXY_MM}# Or, use HEIGHT and XY to specify text position :XY ${X_MM} ${Y_MM}HEIGHT ${HEIGHT_MM}ROTATION ${DEGREES}SCALE ${SCALE}INVERSE ${YES | NO}FRAME ${YES | NO}MARGIN ${MARGIN_MM}READING ${NORMAL | BACKWARDS}B_TEXT${LINE1}${LINE2}...${LINEN}E_TEXTE_TEXT_ANNOTATION
xxxxxxxxxxvirtual int Write_to_file(const char* file_path) const = 0;Reset options to default values
xxxxxxxxxxvirtual void Reset() = 0;Create a new copy from another instance
MUST be eventually destroyed using QisMRTCR::Destroy_object() to avoid resource leak
xxxxxxxxxxvirtual QisMRTCRAnnotations* Clone(const QisMRTCRAnnotations* opts) = 0;QisMRTCRCorrectionsRepresents a specification for applying corrections
Cast this class pointer to any other version (base/derived)
The version number is embedded in the class name in form of a suffix V
Get the latest version number supported by this implementation
xxxxxxxxxxvirtual const char* QisMRTCRCorrections_name(const int version) const = 0;virtual void* QisMRTCRCorrections_cast(const int version) = 0;virtual const void* QisMRTCRCorrections_cast(const int version) const = 0;virtual int QisMRTCRCorrections_latest_version() const = 0;Get information about an error
ecode : non-zero value indicating an error
Get_error_msg() returns the error details
Get_error_condition() returns the error tag to identify the error See qismrtcr.error.h
xxxxxxxxxxvirtual const char* Get_error_msg(const int ecode) const = 0;virtual const char* Get_error_condition(const int ecode) const = 0;Set/Get the tolerance (in file units) for differentiating corrected references to the same cell occuring at different locations
Default : 0.0
xxxxxxxxxxvirtual void Set_tolerance(const double value) = 0;virtual double Get_tolerance() const = 0;Add a correction domain to the existing set
x1, y1 .. x4, y4 - co-ordinates of the points (in file units) in the source data where the correction is known
dx1, dy1 .. dx4, dy4 - Offsets/correction (in file units) at the specified points
xxxxxxxxxxvirtual void Add_domain( const double x1, const double y1, const double dx1, const double dy1, const double x2, const double y2, const double dx2, const double dy2, const double x3, const double y3, const double dx3, const double dy3, const double x4, const double y4, const double dx4, const double dy4 ) = 0;Add domains from a text file
Domains MUST come in sets of four (points/lines)
Syntax:
${X}, ${Y}, ${DX}, ${DY} (on each new line)
xxxxxxxxxxvirtual int Add_from_file(const char* file_path) = 0;Get number of domains (0 implies no correction)
xxxxxxxxxxvirtual int Get_domain_count() const = 0;Get the values for a specific domain
index : Position in the list. 0 <= index < Get_domain_count()
x1, y1 .. x4, y4 - buffers for co-ordinates of the points (in file units)
in the source data where the correction is known
dx1, dy1 .. dx4, dy4 - buffers for offsets/correction (in file units) at the specified points
Return : 0 (success). Otherwise, call Get_error_msg(), Get_error_condition() for error details (index out of bounds)
xxxxxxxxxxvirtual int Get_domain( const int index, double& x1, double& y1, double& dx1, double& dy1, double& x2, double& y2, double& dx2, double& dy2, double& x3, double& y3, double& dx3, double& dy3, double& x4, double& y4, double& dx4, double& dy4 ) = 0;Create a text file from the specified domains
file_path : Path where the text file will be created
Syntax is same as the file imported using Add_from_file()
Return : 0 (success). Otherwise, call Get_error_msg(), Get_error_condition() for error details
xxxxxxxxxxvirtual int Write_to_file(const char* file_path) const = 0;Reset options to default values (clear all domains)
xxxxxxxxxxvirtual void Reset() = 0;Create a new copy from another instance
MUST be eventually destroyed using QisMRTCR::Destroy_object() to avoid resource leak
xxxxxxxxxxvirtual QisMRTCRCorrections* Clone(const QisMRTCRCorrections* opts) = 0;QisMRTCROptsRepresents the various options used for creating a job using
QisMRTCR::Setup_job
xxxxxxxxxxclass QisMRTCROpts { ... };Cast this class pointer to any other version (base/derived)
The version number is embedded in the class name in form of a suffix V
Get the latest version number supported by this implementation
xxxxxxxxxxvirtual const char* QisMRTCROpts_name(const int version) const = 0;virtual void* QisMRTCROpts_cast(const int version) = 0;virtual const void* QisMRTCROpts_cast(const int version) const = 0;virtual int QisMRTCROpts_latest_version() const = 0;Set/Get a spec. for loading/filtering layers when a GDSII/OASIS file is being loaded
layer_map : layer specification. It can have two forms:
Simple list - "1,2:2,3:0,3:2,4" -- Load only layers 1:* 2:2 3:0 3:2 and 4:* (drop all other layer:datatype). The dropped layers will not be available for the life of that database
Layer map - "ALL-NULL,1-100,2:2-200:0,3:0-300:0,3:2-302:0,4-400" --
Load and map 1:* as 100:, 2:2 as 200:0, 3:0 as 300:0, 3:2 as 302:0, 4: as 400:*
All other layer:datatype are dropped
The loaded layers will only be recognized with their new numbers during the life of the database i.e there is no such layer as 2:2 once the database is created.
All data from 2:2 has been moved to 200:0
Default: All layers are loaded as-is from the source file
xxxxxxxxxxvirtual void Set_layers(const char* layer_map) = 0;virtual const char* Get_layers() const = 0;Control how the database is loaded
In disk mode (from_disk == true), the actual CAD data resizes on disk in the original file. Operations can be slower but the memory footprint is smaller. Best for extremly large files
In memory mode (from_disk == false), the CAD data is loaded into memory and nothing is accessed from the disk. Operations are faster but the memory footprint is larger. Best for most cases
Default: load to memory (from_disk == false)
xxxxxxxxxxvirtual void Set_load_from_disk(const bool from_disk) = 0;virtual bool Get_load_from_disk() const = 0;Keep temporary working files for troubleshooting
If on_off == true, temporary working and log files are retained for inspection. Otherwise, they are deleted during End_job()
Default: off (on_off == false)
xxxxxxxxxxvirtual void Set_keep_working_files(const bool on_off) = 0;virtual bool Get_keep_working_files() const = 0;Reset options to default values
xxxxxxxxxxvirtual void Reset() = 0;Create a new copy from another instance
MUST be eventually destroyed using QisMRTCR::Destroy_object() to avoid resource leak
xxxxxxxxxxvirtual QisMRTCROpts* Clone(const QisMRTCROpts* opts) = 0;QisMRTCRasterizerRepresents a single rasterizer object. Multiple rasterizers can co-exist and work in independent application threads
xxxxxxxxxxclass QisMRTCRasterizer;QisMRTCRImageArgsRepresents a set of options for controlling the characteristics of each raster image
Create using QisMRTCR::Create_object("QisMRTCRImageArgs") and destroy using QisMRTCR::Destroy_object("QisMRTCRImageArgs", ..)
xxxxxxxxxxclass QisMRTCRImageArgs { ... };xxxxxxxxxxenum Type { IMG_ARG_INVERT=1 /* image polarity inversion + value type: int (0 | 1) + default: 0 int on_off = 0; Set_arg(QisMRTCRImageArgs::IMG_ARG_INVERT, on_off); Get_arg(QisMRTCRImageArgs::IMG_ARG_INVERT, &on_off); */ ,IMG_ARG_R2L /* mirror image along X (right-to-left) + value type: int (0 | 1) + default: 0 int on_off = 0; Set_arg(QisMRTCRImageArgs::IMG_ARG_R2L, on_off); Get_arg(QisMRTCRImageArgs::IMG_ARG_R2L, &on_off); */ ,IMG_ARG_B2T /* mirror image along Y (bottom-to-top) + value type: int (0 | 1) + default: 0 int on_off = 0; Set_arg(QisMRTCRImageArgs::IMG_ARG_B2T, on_off); Get_arg(QisMRTCRImageArgs::IMG_ARG_B2T, &on_off); */ ,IMG_ARG_SHIFT_TYPE /* pixel shift type (use with IMG_ARG_SHIFT_X or IMG_ARG_SHIFT_Y) + value type: int (one of QisMRTCRFlags::Shift_type), + default: QisMRTCRFlags::SHIFT_NONE int type = QisMRTCRFlags::SHIFT_NONE; Set_arg(QisMRTCRImageArgs::IMG_ARG_SHIFT_TYPE, type); Get_arg(QisMRTCRImageArgs::IMG_ARG_SHIFT_TYPE, &type); */ ,IMG_ARG_SHIFT_X /* column values for pixel shifting (to be used with IMG_ARG_SHIFT_TYPE) + value type: int (no. columns), const long long* (list of column values) + default: 0, NULL int nx = 0; const long long* x_list = 0; Set_arg(QisMRTCRImageArgs::IMG_ARG_SHIFT_X, nx, x_list); Get_arg(QisMRTCRImageArgs::IMG_ARG_SHIFT_X, &nx, &x_list); + the specified list MUST be valid for the duration of it's use during rasterization */ ,IMG_ARG_SHIFT_Y /* row values for pixel shifting (to be used with IMG_ARG_SHIFT_TYPE) + value type: int (no. rows), const long long* (list of row values) + default: 0, NULL int ny = 0; const long long* y_list = 0; Set_arg(QisMRTCRImageArgs::IMG_ARG_SHIFT_Y, ny, y_list); Get_arg(QisMRTCRImageArgs::IMG_ARG_SHIFT_Y, &ny, &y_list); + the specified list MUST be valid for the duration of it's use during rasterization */ ,IMG_ARG_MASK /* set of polygons to form a mask + value type: const NsQisMRaster::QisMRasterPolygonSet* + default: NULL const NsQisMRaster::QisMRasterPolygonSet* set = 0; Set_arg(QisMRTCRImageArgs::IMG_ARG_MASK, set); Get_arg(QisMRTCRImageArgs::IMG_ARG_MASK, &set); + the specified set MUST be valid for the duration of it's use during rasterization */};Cast this class pointer to any other version (base/derived)
The version number is embedded in the class name in form of a suffix V
Get the latest version number supported by this implementation
xxxxxxxxxxvirtual const char* QisMRTCRImageArgs_name(const int version) const = 0;virtual void* QisMRTCRImageArgs_cast(const int version) = 0;virtual const void* QisMRTCRImageArgs_cast(const int version) const = 0;virtual int QisMRTCRImageArgs_latest_version() const = 0;Set/Get image args
arg_type is the type of arg (one of QisMRTCRImageArgs::Type)
the values passed to the variable argument list (...) depends on the type See QisMRTCRImageArgs for details
returns false if arg_type is not recognized. otherwise returns true
xxxxxxxxxxvirtual bool Set_arg(const int arg_type, ...) = 0;virtual bool Get_arg(const int arg_type, ...) const = 0;Reset args to default values
See QisMRTCRImageArgs for default values for various args
xxxxxxxxxxvirtual void Reset() = 0;Copy args from another object or create a clone from the current object
the new object created by Clone() MUST be eventually destroyed using QisMRTCR::Destroy_object("QisMRTCRImageArgs", ..)
xxxxxxxxxxvirtual bool Copy(const QisMRTCRImageArgs* args) = 0;virtual QisMRTCRImageArgs* Clone() const = 0;QisMRTCRJobRepresents a single QisMRTCR job
xxxxxxxxxxclass QisMRTCRJob { ... };Cast this class pointer to any other version (base/derived)
The version number is embedded in the class name in form of a suffix V
Get the latest version number supported by this implementation
xxxxxxxxxxvirtual const char* QisMRTCRJob_name(const int version) const = 0;virtual void* QisMRTCRJob_cast(const int version) = 0;virtual const void* QisMRTCRJob_cast(const int version) const = 0;virtual int QisMRTCRJob_latest_version() const = 0;Get information about an error
ecode : non-zero value indicating an error
Get_error_msg() returns the error details
Get_error_condition() returns the error tag to identify the error See qismrtcr.error.h
xxxxxxxxxxvirtual const char* Get_error_msg(const int ecode) const = 0;virtual const char* Get_error_condition(const int code) const = 0;Get the QisMFile handle (file database) associated with this job
see QisMFile API in qismfile.h to use the various features of this API
xxxxxxxxxxvirtual NsQisMLib::QisMFile* File_db() = 0;Get the path of the directory associated with this job
xxxxxxxxxxvirtual const char* Get_directory() const = 0;Compute size of a pixel (in file units) from dots-per-inch and visa-versa (dpi,pxs > 0.0)
for rectangular pixels (DPI_x != DPI_y), use this method for each dimension separately
xxxxxxxxxxvirtual double DPI_to_pixelsize(const double dpi) const = 0;virtual double Pixelsize_to_DPI(const double pxs) const = 0;Create/destroy a rasterizer object for generating raster images
ecode : buffer to receive the error code if Create_rasterizer() returns NULL
pixelsize_x, pixelsize_y : image resolution expressed as the size of a pixel in file units
cell : name of the view cell. NULL or "" implies default top cell
std_layers : comma separated list of layers to be rasterized normally (dither = 1.0). NULL or "" implies all loaded layers
dither_layers : comma separated list of layers to be rasterized with a specific dither value (using a 8x8 Bayer matrix). NULL or "" implies no dither layers
dither : value for dither_layers (0.0 <= dither <= 1.0)
thrnum : no. threads (>=0) to be used for generating each raster image (0 implies automatic implies no. cpu cores)
argc, argt, argv : reserved for future/internal use
handle : handle of a valid rasterizer object to be destroyed
Return : Create_rasterizer() returns a non-null handle to the rasterizer object on success. Otherwise, call Get_error_msg(), Get_error_condition() for error details using *ecode
Requires ONE license of QISMCODE_RASTER (14827) per call to Create_rasterizer(). This is eventually released by Destroy_rasterizer()
Every rasterizer created using Create_rasterizer() MUST be destroyed using Destroy_rasterizer() to avoid resource/license leaks
Multiple QisMRTCRasterizer objects can co-exist and can be used in independent threads for rastering multiple images in parallel
Create_rasterizer(), Destroy_rasterizer() are NOT thread-safe. They should be called ONLY from the main thread. Once created, the rasterizer methods are thread safe
xxxxxxxxxxvirtual QisMRTCRasterizer* Create_rasterizer( int* ecode, const double pixelsize_x, const double pixelsize_y, const char* cell = 0, const char* std_layers = 0, const char* dither_layers = 0, const double dither = 1.0, const int thrnum = 0, const int argc = 0, const char* const* argt = 0, void* const* argv = 0 ) = 0;virtual void Destroy_rasterizer(QisMRTCRasterizer* handle) = 0;Generate a raster image
image : buffer to receive the image handle
rasterizer : handle to the raster object created using Create_rasterizer()
lx, ly, ux, uy : data extents in file units for the image
invert : if true, background is black (1), foreground is white (0)
right_to_left : if true, lx (minx) appears on the right side of the image
shift_type : type of pixel shifting
n_x, x_list : list of pixel positions (along x) to apply shifting
n_y, y_list : list of pixel positions (along y) to apply shifting
polygon_mask : a set of polygons to serve as a mask over the raster image
Use QisMRaster::New_object(), QisMRaster::Delete_object() (qismraster.h) to create/destroy the set and use QisMRasterPolygonSet::Add_polygon() to add polygons
Return : 0 (success). Otherwise call Get_error_msg(), Get_error_condition() for error details
This method IS THREAD SAFE as long as each thread uses it's own QisMRTCRasterizer object. It's UNSAFE to use the same QisMRTCRasterizer accross multiple threads simultaneously
If dithered layers are specified, these layers are rasterized first
QisMRTCRasterizer manages the raster buffer internally. It re-uses the image buffer if the image size is unchanged, re-allocates only if required and destroys it at the end of it's life. DO NOT delete/free the image buffer externally. DO NOT store the image buffer pointer for later use as it's only guaranteed to be valid until the next call to Get_raster_image() (for the same rasterizer)
It's OK to modify the image pixels as long as the access is within the bounds of the image buffer. Just use const_cast<unsigned char*>(QisMRasterImage::Image_buffer()) to make changes
The image is composed in the following sequence :
Rasterize dithered layers (optional)
Overlay standard layers
Apply pixel shifts (optional)
Apply polygon mask (optional)
xxxxxxxxxxvirtual int Get_raster_image( const NsQisMRaster::QisMRasterImage*& image, QisMRTCRasterizer* rasterizer, const double lx, const double ly, const double ux, const double uy, const bool invert = false, const bool right_to_left = false, const QisMRTCRFlags::Shift_type shift_type = QisMRTCRFlags::STF_NONE, const int n_x = 0, const long long* x_list = 0, const int n_y = 0, const long long* y_list = 0, const NsQisMRaster::QisMRasterPolygonSet* polygon_mask = 0 ) = 0;QisMRTCRJobV2QisMRTCRJob extension #2 with support for per image corrections
xxxxxxxxxxclass QisMRTCRJobV2: public QisMRTCRJob { ... };Create a rasterizer object with additional corrections to be applied just before rasterization
It's identical to QisMRTCRJob::Create_rasterizer except:
correction_xy is an array of xy co-ordinates of the measured points with correction. It consists of groups of 4 values (in file-units) x,y,dx,dy where x,y are the co-ordinates of the reference point and dx,dy is the measured displacement. correction_xy = double[npts * 4]
npts is the no. measured points. If npts == 0, the four corners of the home view are used without displacements (corrected polygons = source polygons)
This method is identical to QisMRTCRJob::Create_rastaerizer if npts == 0 or correction_xy == NULL
Requires Requires ONE license of QISMCODE_RASTER (14827) and QISMCODE_CORRX (11093) per call
The specified corrections will be applied to every image generated using this rasterizer
Create_corrx_rasterizer(), is NOT thread-safe. It should be called ONLY from the main thread. Once created, the rasterizer methods are thread safe
See QisMRTCRJob::Create_rasterizer for information that applies to both
xxxxxxxxxxvirtual QisMRTCRasterizer* Create_corrx_rasterizer( int* ecode, const double pixelsize_x, const double pixelsize_y, const double* correction_xy, const int npts, const char* cell = 0, const char* std_layers = 0, const char* dither_layers = 0, const double dither = 1.0, const int thrnum = 0, const int argc = 0, const char* const* argt = 0, void* const* argv = 0 ) = 0;QisMRTCRJobV3QisMRTCRJob extension #3 for a Get_raster_image alternative with image options
xxxxxxxxxxclass QisMRTCRJobV3: public QisMRTCRJobV2 { ... };Generate a raster image
image : buffer to receive the image handle
rasterizer : handle to the raster object created using Create_rasterizer()
lx, ly, ux, uy : data extents in file units for the image
opts : options to control the characteristics of the image. see QisMRTCRImageArgs
Return : 0 (success). Otherwise call Get_error_msg(), Get_error_condition() for error details
This method IS THREAD SAFE as long as each thread uses it's own QisMRTCRasterizer object. It's UNSAFE to use the same QisMRTCRasterizer accross multiple threads simultaneously
If dithered layers are specified, these layers are rasterized first
QisMRTCRasterizer manages the raster buffer internally. It re-uses the image buffer if the image size is unchanged, re-allocates only if required and destroys it at the end of it's life. DO NOT delete/free the image buffer externally. DO NOT store the image buffer pointer for later use as it's only guaranteed to be valid until the next call to Get_raster_image() (for the same rasterizer)
It's OK to modify the image pixels as long as the access is within the bounds of the image buffer. Just use const_cast<unsigned char*>(QisMRasterImage::Image_buffer()) to make changes
The image is composed in the following sequence :
Rasterize dithered layers (optional)
Overlay standard layers
Apply pixel shifts (optional)
Apply polygon mask (optional)
xxxxxxxxxxvirtual int Get_raster_image_opts( const NsQisMRaster::QisMRasterImage*& image, QisMRTCRasterizer* rasterizer, const double lx, const double ly, const double ux, const double uy, const QisMRTCRImageArgs* opts = 0 ) = 0;QisMRTCRJobV4QisMRTCRJob extension #4 with support for per image corrections
xxxxxxxxxxclass QisMRTCRJobV4: public QisMRTCRJobV3 { ... };Get a handle to the RTCR (extension) API
xxxxxxxxxxvirtual QisMRTCR* RTCR_api() = 0;virtual const QisMRTCR* RTCR_api_const() const = 0;QisMRTCRRepresents the manager/gateway for the QisMRTCR extension for QisMLib
xxxxxxxxxxclass QisMRTCR: public NsQisMLib::QisMExtensionAPI { ... };Cast this class pointer to any other version (base/derived)
The version number is embedded in the class name in form of a suffix V
Get the latest version number supported by this implementation
xxxxxxxxxxvirtual const char* QisMRTCR_name(const int version) const = 0;virtual void* QisMRTCR_cast(const int version) = 0;virtual const void* QisMRTCR_cast(const int version) const = 0;virtual int QisMRTCR_latest_version() const = 0;Get information about an error
ecode : non-zero value indicating an error
Get_error_msg() returns the error details
Get_error_condition() returns the error tag to identify the error
See qismrtcr.error.h
xxxxxxxxxxvirtual const char* Get_error_msg(const int ecode) const = 0;virtual const char* Get_error_condition(const int ecode) const = 0;Create/Destroy a data structure object
class_name : name of the class whose object is to be created/destroyed acceptable values: "QisMRTCROpts", "QisMRTCRCorrections", "QisMRTCRAnnotations", "QisMRTCRImageArgs"
handle : handle of the object (of the appropriate class) to be destroyed
Create_object() returns NULL if the class_name is invalid/unrecognized
return of Create_object() MUST be type-casted to the specified class for use
Every object created using Create_object() MUST be destroyed ONLY using Destroy_object() to avoid resource leaks
xxxxxxxxxxvirtual void* Create_object(const char* class_name) = 0;virtual void Destroy_object(const char* class_name, void* handle) = 0;Create an instance of the QisMRTCR job
job : buffer to receive the handle of the newly created job
job_dir : path to an existing writable directory where the output and working files will be created
lib_h : handle to QisMLib API obtained from QisMLib_initialize_once (qismlib.h)
file_path : path of a GDSII file to be used as the source for the job
basic_opts : basic options
progress : callback handler to receive progress updates
corrections_opts : options for applying corrections
annotations_opts : options for applying annotations
argc, argt, argv : reserved for internal/future use
Return : 0 (success) job will contain a non-NULL handle to the newly created job. Otherwise, use Get_error_msg(), Get_error_condition() for error details
Requires ONE license of QISMCODE_RTCR (1303) per call
Every job created using this method MUST be eventually closed using End_job() to avoid resource/license leaks
Multiple jobs can co-exitst at the same time
This method is NOT THREAD-SAFE. It should be called only in the main thread
xxxxxxxxxxvirtual int Setup_job( QisMRTCRJob*& job, const char* job_dir, NsQisMLib::QisMLib* lib_h, const char* file_path, QisMRTCROpts* basic_opts, NsQisMLib::QisMNotify* progress, QisMRTCRCorrections* corrections_opts = 0, QisMRTCRAnnotations* annotations_opts = 0, const int argc = 0, const char* const* argt = 0, void* const* argv = 0 ) = 0;Close an instance of the QisMRTCR job and release it's resources
handle : handle of the job to be closed
Releases ONE license of QISMCODE_RTCR per call
Every job created using Setup_job() MUST be eventually closed using End_job() to avoid resource/license leaks
Multiple jobs can co-exitst at the same time
This method is NOT THREAD-SAFE. It should be called only in the main thread
xxxxxxxxxxvirtual void End_job(QisMRTCRJob* handle) = 0;QisMRTCRV2Extension for
QisMRTCR(version = 2)
xxxxxxxxxxclass QisMRTCRV2: public QisMRTCR { ... };Get a handle to the core rasterizer (from QisMRaster)
xxxxxxxxxxvirtual NsQisMRaster::QisMRasterizer* Rasterizer_core( QisMRTCRasterizer* rasterizer ) = 0;String error codes (tags) returned by
*::Get_error_condition()
*::Get_error_msg() returns the human-readable description of that error
xxxxxxxxxx/* failed to apply annotations/corrections *//* failed to create rasterizer object *//* failed to open a file for reading/writing *//* specified index is out of bounds *//* specified box extents are invalid *//* specified dir path is empty/null *//* specified file path in empty/null *//* specified grid is invalid *//* specified handle is null *//* specified height is invalid *//* specified text string is empty/null *//* failed to load a GDSII/OASIS file *//* specified dir is not a directory *//* specified file to be loaded is not a GDSII file *//* failed to locate a required qism-extension *//* one or more extension APIs are missing required features *//* the specified file has no layers or no non-dither layers *//* the specified cell does not exist *//* error generating the raster image *//* failed to apply pixel shifting *//* failed to apply polygon mask *//* failed to acquire RTCR license *//* failed to create corrections object *//* failed to get corrected polygons */Requires the QisMRTCR extension to be installed and loaded (qismrtcr64.dll/so)
Select commands may require a valid license
See qismrtcr.h for the corresponding API
xxxxxxxxxxrtcr.create_opts &opts={opts_id} [layers={layer_filter}] [diskload] [keeptmp]
Create a new instance of the basic RTCR options object (QisMRTCROpts*)
Equivalent to QisMRTCR::Create_object("QisMRTCROpts") in qismrtcr.h
{opts_id} represents name of the variable of type QisMRTCROpts* associated with the newly created object
{layer_filter} if used, can be a comma-separated list of layers w/o datatypes OR a layer map
e.g "1,2:2,3" for a simple list of layers of interest
e.g "ALL-NULL,1-100,2:2-200:0,3-300:3" for a layer map that re-maps 1:* to 100:*, 2:2 to 200:0 and merges all datatypes of layer 3 to 300:3
diskload if used creates the new database in 'disk' mode to reduce the memory footprint
keeptmp if used will retain the temporary files used by an RTCR job in it's job directory after the job has been closed. This can be useful for troubleshooting and diagnosis
Every object created using this command MUST be destroyed by the script using rtcr.destroy_opts to avoid resource leak
xxxxxxxxxxrtcr.destroy_opts $opts={opts_id}
Destroy an instance of the basic RTCR options object
Equivalent to QisMRTCR::Destroy_object("QisMRTCROpts") in qismrtcr.h
{opts_id} represents name of the variable of type QisMRTCROpts* associated with the object to be destroyed
xxxxxxxxxxrtcr.create_corrections&corr={corr_id}{{point={x},{y},{dx},{dy}}+4x} | file={corr_file}[tolerance={value}]
Create an instance of the RTCR corrections object
Equivalent to QisMRTCR::Create_object("QisMRTCRCorrections") in qismrtcr.h
{corr_id} represents name of the variable of type QisMRTCRCorrections* associated with the newly created object
{x},{y},{dx},{dy} represents one correction point. Each domain contains exactly FOUR such points. Specify one or more domains using a series of point= arguments
{corr_file} represents the path of a correction text file to be imported. See QisMRTCRCorrections in qismrtcr.h for file syntax
{value} represents the amount of tolerance to be applied for correcting cell references
Every object created using this command MUST be destroyed by the script using rtcr.destroy_corrections to avoid resource leak
xxxxxxxxxxrtcr.destroy_corrections $corr={corr_id}
Destroy an instance of the RTCR corrections object
Equivalent to QisMRTCR::Destroy_object("QisMRTCRCorrections") in qismrtcr.h
{corr_id} represents name of the variable of type QisMRTCRCorrections* associated with the object to be destroyed
xxxxxxxxxxrtcr.create_annotations &ann={ann_id} [file={ann_file}]
Create an instance of the RTCR annotations object
Equivalent to QisMRTCR::Create_object("QisMRTCRAnnotations") in qismrtcr.h
{ann_id} represents name of the variable of type QisMRTCRAnnotations* associated with the newly created object
{ann_file} if specified, represents the path of a annotation text file to be imported. See QisMRTCRAnnotations in qismrtcr.h for file syntax
Every object created using this command MUST be destroyed by the script using rtcr.destroy_annotations to avoid resource leak
xxxxxxxxxxrtcrannotations.add$ann={id}text={string}{pos={x},{y},{height} | box={lx},{ly},{ux},{uy}}units_m={value}[angle={degrees}][margin={mm_value}][inverse][frame][backwards]
Add one annotation item to a list of annotations. This command can be called multiple times to add more annotations to a single job
{id} is name of a variable of type QisMRTCRAnnotations* associated with the annotations settings object obtained via rtcr.create_annotations
{string} is the annotation text
{x},{y},{height} are the position and size of the annotation in file units. The width is calculated based on the text string and the height. Alternately, the annotation can be fit into a fixed size bounding box with min-max extents {lx} .. {uy}. One of these two options MUST be specified
units_m is the file units in meters. e.g um = 1e-6
angle is the rotation to be applied to the text. In box mode, the rotated text is made to fit inside the specified box. The box itself is not rotated
margin is the amount of margin (in mm) to be applied between the text and the outer frame when frame is enabled
frame if specified places the text inside a frame
inverse if specified inverts the polarity of the text polygons (the text is subtracted from a base rectangle)
backwards if specified reverses the appearance of the text so that it reads backwards
xxxxxxxxxxrtcr.destroy_annotations $ann={ann_id}
Destroy an instance of the RTCR annotations object
Equivalent to QisMRTCR::Destroy_object("QisMRTCRAnnotations") in qismrtcr.h
{ann_id} represents name of the variable of type QisMRTCRAnnotations* associated with the object to be destroyed
xxxxxxxxxxrtcr.setup_job&job={job_id}outdir={output_dir}input={input_gdsii}[$opts={opts_id}][$corr={corr_id}][$ann={ann_id}]
Create a new RTCR job and a new database associated with it
Equivalent to QisMRTCR::Setup_job in qismrtcr.h
Requires 1 license of (1303) which will be released during rtcr.end_job
RTCR job represents a database created from a micron (um) GDSII file optionally with corrections and annotations
{job_id} represents name of the variable of type QisMRTCRJob* associated with the newly created job
{output_dir} is the path of an existing directory to be used as a working directory for this job
{input_gdsii} is the path of the source GDSII file. It MUST has micron units. Usually, it would be generated by SFGen
{opts_id} if used, represents name of the variable of type QisMRTCROpts* associated with the RTCR basic options object created using rtcr.create_opts
{corr_id} if used, represents name of the variable of type QisMRTCRCorrections* associated with RTCR corrections object created using rtcr.create_corrections
{ann_id} if used, represents name of the variable of type QisMRTCRAnnotations* associated with RTCR annotations object created using rtcr.create_annotations
Every job created using this command MUST be eventually destroyed using rtcr.end_job to avoid resource leaks
This command also creates a new script variable of type QisMFile* with the name {job_id} so that it can be used wherever QisMFile can be used. DO NOT use this variable with lib.unload_file as the associated database will be destroyed automatically during rtcr.end_job
xxxxxxxxxxrtcr.end_job $job={job_id}
Destroy an RTCR job and the database associated with it
Equivalent to QisMRTCR::End_job in qismrtcr.h
Releases 1 license of (1303) acquired during rtcr.setup_job
{job_id} represents name of the variable of type QisMRTCRJob* associated with the job to be destroyed
xxxxxxxxxxrtcrjob.create_rasterizer$job={job_id}&rstr={rasterizer_id}{pixelsize={x}[,{y}] | dpi={x}[|{y}]}[cell={cellname}][layers={std_layers}][dlayers={dither_layers}][dither={0.0-1.0}][thrnum={num_threads}]{correct={x},{y},{dx},{dy}}*
Create a new rasterizer object associated with a particular RTCR job
Equivalent to QisMRTCRJob::Create_rasterizer in qismrtcr.h
Requires 1 license of (14827) per call which will be released during rtcrjob.destroy_rasterizer
{job_id} represents name of the variable of type QisMRTCRJob* associated with the newly created job
{rasterizer_id} represents name of the variable of type QisMRTCRasterizer* associated with the newly created rasterizer object
{x},{y} represents the desired image resolution in DPI (dots per inch) or as a pixel size (in file units). The {y} value is optional. If not used, the resolution is uniform along X and Y axes
{cellname} is name of the view cell. If not used, the default top cell is used as the view cell
{std_layers} is a comma-separated list of layers representing the layers to be rasterized in each image. If not used, ALL layers in the database as rasterized in each image. e.g layers=1,2:2,3:0,3:3,4
{dither_layers} is a comma-separated list of layers to be rasterized with the specified dither value. If not used, dithering is disabled for the subsequent images. Dithering is applied using a 8x8 bayer matrix
{num_threads} is the number of threads to be used to generate each raster image
Use one or more correct={x},{y},{dx},{dy} to apply second-level corrections to any image generated using this rasterizer object. By default, no additional corrections are applied to rasterized images. Applying second-level corrections requires 1 license of (11093) in addition to (14827) per rasterizer object
Each rasterizer created using this command MUST be destroyed eventually using rtcrjob.destroy_rasterizer to avoid resource leaks
xxxxxxxxxxrtcrjob.get_raster_image$job={job_id}$rstr={rasterizer_id}$windows={window_set_id}[invert][right_to_left][shiftpx={INS_B | INS_W | REM}][pxrows={px}[,{px}]*][pxcols={px}[,{px}*]][format={TIF | BMP | RAW}]
Generate one or more raster images
Equivalent to multiple calls to QisMRTCRJob::Get_raster_image in qismrtcr.h
{job_id} represents name of the variable of type QisMRTCRJob* associated with the job in question
{rasterizer_id} represents name of the variable of type QisMRTCRasterizer* associated with the rasterizer to used for generating these images
{window_set_id} represents name of the variable of type QisMBoxSet* associated with a set of windows created using script.new_window_set
invert is used, inverts the image polarity to white-on-black i.e bit=0 for data, bit=1 for background
right_to_left rasterizes the image from right to left i.e min-x of the data appears on the right hand size of the raster image
shiftpx, pxrows and/or pxcols is used, apply row/column shifting to each image. {px} represents a row/column number in pixel space (MUST be within the bounds of the image). pixel 0,0 appears at the top-left corner of the image. INS_B inserts a black line (white line in invert mode), INS_W inserts a white line (black line in invert mode) and REM removes a line. The image size does not change in either case
format is used writes the image to disk in TIFF, BMP or RAW format. The job directory is used as the output directory. The name of each file is derived from the associated window-name (see script.new_window_set)
xxxxxxxxxxrtcr.destroy_rasterizer $job={job_id} $rstr={rasterizer_id}
Destroy a rasterizer object
Equivalent to QisMRTCRJob::Destroy_rasterizer in qismrtcr.h
Releases 1 license of (14827) acquired during rtcrjob.create_rasterizer
{rasterizer_id} represents name of the variable of type QisMRTCRasterizer* associated with the rasterizer to be destroyed
{job_id} represents name of the variable of type QisMRTCRJob* associated with the job that created the rasterizer in question
Product name :
QisMRTCRLicense code :1303
| Operation | License Code | Policy |
|---|---|---|
| Setup_job | QisMRTCR | Check-out ONE license per call |
| End_job | QisMRTCR | Check-in ONE license per call |
| Create_rasterizer | QisMRaster | Check-out ONE license per call |
| Create_corrx_rasterizer | QisMRaster,QisMCorrX | Check-out ONE license of each per call |
| Destroy_rasterizer | QisMRaster,QisMCorrX | Check-in ONE license (of each) per call |
Product name :
QisMRTCRLicense code :1303
| Operation | License Code | Policy |
|---|---|---|
| rtcr.setup_job | QisMRTCR | Check-out ONE license per call |
| rtcr.end_job | QisMRTCR | Check-in ONE license per call |
| rtcrjob.create_rasterizer | QisMRaster,QisMCorrX | Check-out ONE license of each per call |
| rtcrjob.destroy_rasterizer | QisMRaster,QisMCorrX | Check-in ONE license (of each) per call |
Support for TIF8 in script commands
Support for 2x2 subsampling
VS 2015 port
Bug fix - adding annotations
bug fix: top row of a raster image was blank
New API QisMRTCRJobV3::Get_raster_image_opts as an alternative to QisMRTCRJob::Get_raster_image for specifying additional image options
Script command rtcrjob.get_raster_image has a new option bottom_to_top
QisMScript command rtcr.create_rasterizer has been updated to support second level corrections
New feature (QisMRTCRJobV2) to create a rasterizer object with the ability to apply second level corrections to every image generated by it
Misc. bug fixes
First cut
Last Updated -- Sun Apr 6 20:06:38 UTC 2025