/** \file epscompress.c
*
* Compresses an EPS file generated from Matlab using the LZW
* algorithm.
*
* According to most sources, the patents for LZW compression expired
* around 2003--2004. If this is incorrect, please let the author know.
*
* This particular algorithm uses an unbalenced binary search tree to
* determine if a string exists in the dictionary.
*
* Version 0.2 10-Sep-2010
*
* See the license at the bottom of the file.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mex.h"
/* Maximum table size, 2^MaxBits */
#define TABLESIZE 4096
/* Number of branches for each node */
#define TABLEDEPTH 3
/* Locations of each tree branch */
#define CHILD 0
#define LEFT 1
#define RIGHT 2
/* Max/Min output bit sizes. */
#define BITMAX 12
#define BITMIN 9
/* Special input/output values. */
#define CLEARTABLE 256
#define ENDOFDATA 257
/* First free location in the index. */
#define FIRSTFREE 258
/* Maximum string storage space */
#define MAXSTR 1024
/* Maximum output width. */
#define OUTPUTWIDTH 75
/* Number of lines between DSC comments before compression starts */
#define DSCGRACE 10
/**
* Structure containing information about the current LZW
* compression state.
*/
typedef struct{
/* Index and dictionary tables */
unsigned int Index[ TABLEDEPTH ][ TABLESIZE ];
unsigned char Dictionary[ TABLESIZE ];
/* Current character being processed. */
unsigned char CurrentChar;
/* Current index (equivalent to the prefix). */
int CurrentIndex;
/* Next free index. */
unsigned int NextIndex;
/* Variable to store the maximum index for the current bitsize */
unsigned int MaxIndex;
/* Current output bitsize. */
unsigned int BitSize;
} LZW_State;
/**
* Structure containing information about the IO state.
*/
typedef struct{
/* File pointers */
FILE *fin;
FILE *fout;
unsigned int Storage;
unsigned int ColumnWidth;
int StorageIndex;
} IO_State;
/**
* Initialise LZW_State data structure.
*/
void LZW_State_Init( LZW_State *x )
{
memset( x->Index, 0, sizeof( x->Index ) );
memset( x->Dictionary, 0, sizeof( x->Dictionary ) );
x->CurrentChar = 0;
x->CurrentIndex = -1;
x->NextIndex = FIRSTFREE;
x->MaxIndex = (1<<BITMIN);
x->BitSize = BITMIN;
}
/**
* Initialise IO_State data structure. File pointers
* (fin and fout) need to be initialised seperately.
*/
void IO_State_Init( IO_State *x )
{
x->Storage = 0;
x->ColumnWidth = 0;
x->StorageIndex = 0;
}
/**
* Private function to format the output into at max character widths.
*/
void asciiprv_put( char x, IO_State *y )
{
fputc( x, y->fout );
y->ColumnWidth++;
/* If output is full, print a newline */
if( y->ColumnWidth == OUTPUTWIDTH )
{
fputc( 10, y->fout );
y->ColumnWidth = 0;
}
}
/**
* Takes a variable bit-length raw input stream, and formats it into
* ASCII85 format.
*/
void asciistreamout( unsigned int x, IO_State *y, LZW_State *z )
{
int shift, ii;
const int divisors[] = { 85*85*85*85, 85*85*85, 85*85, 85, 1 };
/* Shift the new data in. */
shift = (32-z->BitSize-y->StorageIndex);
if( shift >= 0 ) y->Storage |= (x<<shift);
else y->Storage |= (x>>-shift);
y->StorageIndex += z->BitSize;
/* If the buffer is full (i.e. 32-bits) output the 5 characters. */
if( y->StorageIndex >= 32 )
{
/* Special case, 0 gets written out as z */
if( y->Storage == 0 ) asciiprv_put( 'z', y );
else
{
/* Otherwise, output the 5 characters. */
for( ii=0; ii<5; ii++ )
{
asciiprv_put( (char)( ( y->Storage/divisors[ii] )%85+33 ), y );
}
}
y->StorageIndex -= 32;
/* Add any left-over bits to the storage. */
if( y->StorageIndex == 0 ) y->Storage = 0;
else y->Storage = (x<<(32-y->StorageIndex));
}
}
/**
* Cleanup the output stream. Outputs whatever partially completed bits
* are present.
*/
void asciistreamout_cleanup( IO_State *y )
{
int ii,numBytes;
const int divisors[] = { 85*85*85*85, 85*85*85, 85*85, 85, 1 };
/* Only output as many bytes as required, as per Adobe ASCII85 */
numBytes = 5 - (32-y->StorageIndex)/8;
for( ii=0; ii<numBytes; ii++ )
{
asciiprv_put( (char)( ( y->Storage/divisors[ii] )%85+33 ), y );
}
/* Cleanup variables, output the 'end of data' string. */
y->StorageIndex = 0;
y->Storage = 0;
y->ColumnWidth = 0;
fprintf(y->fout,"~>");
}
/**
* Update the Dictionary with new values, and outputs the current prefix.
*/
void NotInDictionary( unsigned int fromNode, unsigned int from, IO_State *y, LZW_State *z )
{
int temp;
/* Update the tables */
z->Index[ fromNode ][ from ] = z->NextIndex;
z->Dictionary[ z->NextIndex ] = z->CurrentChar;
z->NextIndex++;
/* Output the current index (prefix) */
asciistreamout( z->CurrentIndex, y, z );
/* Update to the new index (prefix) */
z->CurrentIndex = z->CurrentChar;
/* Check to see if bitsize has been exceeded. */
if( z->NextIndex == z->MaxIndex )
{
if( z->BitSize == BITMAX )
{
asciistreamout( CLEARTABLE, y, z );
temp = z->CurrentIndex;
LZW_State_Init( z );
z->CurrentIndex = temp;
}
else
{
z->BitSize++;
z->MaxIndex = (1<<z->BitSize);
}
}
}
/**
* LZW Compression function.
*/
void LZW( char x, IO_State *y, LZW_State *z)
{
unsigned int X;
if( z->CurrentIndex == -1 )
{
z->CurrentIndex = x;
return;
}
z->CurrentChar = x;
/* Test to see if prefix exists as a child. */
X = z->Index[ CHILD ][ z->CurrentIndex ];
if( X==0 )
{
NotInDictionary( CHILD, z->CurrentIndex, y, z );
return;
}
/* Binary tree search for current string. */
while( 1 )
{
/* If we find a value in the dictionary */
if( z->CurrentChar == z->Dictionary[ X ] )
{
z->CurrentIndex = X;
break;
}
/* Otherwise, search through the tree */
if( z->CurrentChar > z->Dictionary[ X ] )
{
if( z->Index[ RIGHT ][ X ] == 0 )
{
NotInDictionary( RIGHT, X, y, z );
break;
}
else
{
X = z->Index[ RIGHT ][ X ];
}
}
else
{
if( z->Index[ LEFT ][ X ] == 0 )
{
NotInDictionary( LEFT, X, y, z );
break;
}
else X = z->Index[ LEFT ][ X ];
}
}
}
/**
* Main function call in a c-mex environment.
*/
void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
{
const char eps_magic[] = {0xc5,0xd0,0xd3,0xc6,0};
char str[ DSCGRACE ][ MAXSTR ];
int comp_state = 0;
int ii, jj;
IO_State y;
LZW_State z;
IO_State_Init( &y );
LZW_State_Init( &z );
/* Sanity check the inputs */
if( nrhs != 2 ) mexErrMsgTxt("Two input arguments required.\n");
if( nlhs != 0 ) mexErrMsgTxt("Too many output arguments.\n");
if ( !( mxIsChar(prhs[0]) && mxIsChar(prhs[1]) ) )
mexErrMsgTxt("Inputs (filenames) must both be of type string.\n.");
y.fin = fopen( mxArrayToString( prhs[0] ), "r" );
if( y.fin == NULL )
mexErrMsgTxt("Cannot open the input file for reading.\n");
y.fout = fopen( mxArrayToString( prhs[1] ), "w" );
if( y.fout == NULL )
mexErrMsgTxt("Cannot open the output file for writing.\n");
/* Read the header */
fgets( &str[0][0], MAXSTR, y.fin );
if( ( strncmp( &str[0][0], "%!PS-Adobe-", 11 ) && strncmp( &str[0][0], eps_magic, 4 ) ) )
{
fclose(y.fin);
fclose(y.fout);
mexErrMsgTxt("Input file is not an EPS file.\n");
}
fputs( &str[0][0], y.fout );
comp_state = 0;
while( !feof( y.fin ) )
{
str[0][0] = 0;
fgets( &str[0][0], MAXSTR, y.fin );
/* If compression is off */
if( comp_state == 0 )
{
/* If the next line is a DSC comment, output and continue */
if( !strncmp( &str[0][0], "%%", 2 ) ) fputs( &str[0][0], y.fout );
/* Otherwise, determine if we need to start compression by scanning
ahead. */
else
{
for( ii=1; ii<DSCGRACE; ii++ )
没有合适的资源?快使用搜索试试~ 我知道了~
matlabfrag is a function which exports a Matlab figure to
共53个文件
m:42个
tex:2个
mexw64:1个
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 25 浏览量
2023-07-24
19:39:36
上传
评论
收藏 353KB ZIP 举报
温馨提示
matlabfrag is a function which exports a Matlab figure to .eps and .tex files for use in LaTeXpdfLaTeXLyX.zip
资源推荐
资源详情
资源评论
收起资源包目录
matlabfrag is a function which exports a Matlab figure to .eps and .tex files for use in LaTeXpdfLaTeXLyX.zip (53个子文件)
新建文件夹
matlabfrag-master
README 746B
matlabfrag.m 52KB
epscompress.mexglx 12KB
epscompress.mexw64 12KB
examples
test05.m 384B
test01.m 340B
test04.m 502B
test15.m 294B
ex03.m 360B
test07.m 495B
test14.m 383B
test03.m 420B
ex16.m 366B
test19.m 342B
test11.m 350B
test16.m 839B
run_all.m 605B
ex06.m 454B
ex08.m 461B
ex01.m 413B
test13.m 439B
ex11.m 591B
ex07.m 487B
ex05.m 432B
laprint.m 98KB
test06.m 638B
userguide.tex 37KB
comparison01.m 1KB
test17.m 435B
ex10.m 603B
testing.tex 6KB
ex17.m 860B
test12.m 557B
test18.m 396B
ex04.m 440B
test09.m 491B
ex13.m 776B
ex12.m 643B
comparison02.m 1KB
ex15.m 1KB
ex02.m 389B
test02.m 371B
ex14.m 635B
test10.m 397B
ex09.m 473B
test08.m 313B
epscompress.mexmaci64 13KB
epscompress.c 11KB
epscompress.mexmaci 13KB
epscompress.mexa64 13KB
epscompress.mexw32 9KB
userguide.pdf 272KB
package.m 2KB
共 53 条
- 1
资源评论
AbelZ_01
- 粉丝: 901
- 资源: 5441
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 基于yolov3+python实现的计算机视觉的交通场景智能应用,现道路目标如人、车牌、交通灯等物体的识别+数据权重+测试视频
- 基于C++和Yolo5检测和React前端开发的人流量检测系统源码+文档说明+详细注释(高分项目)
- C#毕业设计-跟踪机器人运动坐标并可视化路径轨迹源码+数据库
- 基于浏览器JS做路径跟踪渲染+源代码+界面截图
- 基于USV路径跟踪LOS控制算法matlab仿真源码+详细注释(下载直接使用)(高分项目)
- CentOS7的docker镜像
- 基于C++和Pure-pursuit算法实现的路径跟踪和给予LQR的轨迹跟踪+源代码+文档说明+脚本(高分项目)
- 基于python实现的路径跟踪控制实现的项目源代码+文档说明(高分课程设计)
- 基于神经网络的虚假评论识别系统(Python源码+文档资料+数据集+代码流程说明文档+详细注释)
- 科大讯飞开发者大赛锂离子电池生产参数调控及生产温度预测挑战赛记录python源码
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功