forked from stefslon/savepng
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsavepng.cpp
138 lines (114 loc) · 4.48 KB
/
savepng.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// % SAVEPNG
// % Very fast PNG image compression routine.
// %
// % Input syntax is:
// % savepng(CDATA,filename[,Compression]);
// %
// % Optional parameters:
// % Compression A number between 0 and 10 controlling the amount of
// % compression to try to achieve with PNG file. 0 implies
// % no compresson, fastest option. 10 implies the most
// % amount of compression, slowest option. Default
// % value is 4.
// %
// % Example:
// % img = getframe(gcf);
// % savepng(img.cdata,'example.png');
// %
// % PNG encoding routine based on public-domain MINIZ library:
// % http://code.google.com/p/miniz/
// %
//
// % Author: S.Slonevskiy, 02/18/2013
// % File bug reports at:
// % https://github.com/stefslon/savepng/issues
//
// % Versions:
// % 02/18/2013, Initial version
// % 02/22/2013, Some miniz.c fixes to allow for compilation on LCC
// % 03/14/2014, Brought miniz.c to the latest version r63 (from Oct 13, 2013)
// % Changed compression limits from 0 to 10 to align with miniz
#include <stdio.h>
#include <stdlib.h>
#include "mex.h"
#include "matrix.h"
#include "miniz.c"
/* The gateway function */
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
unsigned char *imgdata; /* packed raw pixel matrix */
unsigned char *indata; /* input image data matrix */
unsigned width, height, nchan; /* size of matrix */
unsigned char max_probes; /* compression level */
const mwSize *dim_array;
unsigned x, y, idx;
unsigned dpm; /* dots per meter */
unsigned char *outdata;
FILE* file;
char *filename;
size_t filenamelen;
size_t filelen;
/* Default number of probes */
max_probes = 4;
/* Default image resolution */
dpm = (96.0*39.36996);
/* Check for proper number of arguments */
if(nrhs<2) {
mexErrMsgIdAndTxt("savepng:nrhs","At least two inputs required.");
}
/* Check if compression level is commanded */
if(nrhs>=3) {
max_probes = mxGetScalar(prhs[2]);
}
/* Check if image resolution is commanded */
if(nrhs>=4) {
dpm = ((double)mxGetScalar(prhs[3])*39.36996);
}
/* Check probes range */
if((max_probes<0) || (max_probes>10)) {
mexErrMsgIdAndTxt("savepng:nrhs","Compression level must be between 0 and 10.");
}
/* Get the number of dimensions in the input argument. */
dim_array = mxGetDimensions(prhs[0]);
if((!mxIsUint8(prhs[0])) || (mxGetNumberOfDimensions(prhs[0])!=3) || !(dim_array[2]==3 || dim_array[2]==4)) {
mexErrMsgIdAndTxt("savepng:nrhs","Input must in the image data format of MxNx3 or MxNx4 matrix of uint8.");
}
/* Pointer to image input data */
indata = (unsigned char *)mxGetPr(prhs[0]);
/* Get dimensions of input matrices */
nchan = dim_array[2];
height = dim_array[0];
width = dim_array[1]; /* this dimension concatenates with the 3rd dimension */
/* Fetch output filename */
filenamelen = mxGetN(prhs[1])*sizeof(mxChar)+1;
filename = (char *)mxMalloc(filenamelen);
mxGetString(prhs[1], filename, (mwSize)filenamelen);
/* Convert MatLab image to raw pixels */
/* indata format: RRRRRR..., GGGGGG..., BBBBBB... */
/* outdata format: RGB, RGB, RGB, ... */
imgdata = (unsigned char *)mxMalloc(width * height * nchan);
idx = 0;
for(y = 0; y < height; y++)
{
for(x = 0; x < width; x++)
{
imgdata[idx++] = indata[x*height + y]; /* red */
imgdata[idx++] = indata[1*width*height + x*height + y]; /* green */
imgdata[idx++] = indata[2*width*height + x*height + y]; /* blue */
if (nchan==4)
imgdata[idx++] = indata[3*width*height + x*height + y]; /* alpha */
}
}
/* Encode PNG in memory */
/* Parameter "3" implies RGB pixel format */
outdata = (unsigned char * )tdefl_write_image_to_png_file_in_memory_ex((unsigned char *)imgdata, width, height, nchan, dpm, &filelen, max_probes, MZ_FALSE);
/* Write to file */
file = fopen(filename, "wb" );
if(!file) return;
fwrite((char*)outdata, 1, filelen, file);
fclose(file);
/* When finished using image data and filename string, deallocate it. */
mxFree(filename);
mxFree(imgdata);
mxFree(outdata);
}