#include <stdio.h>
|
#include <string.h>
|
#include <ctype.h>
|
#include <stdlib.h>
|
|
#include <fpdfview.h>
|
|
static void writedword(FILE *fp, unsigned int d)
|
{
|
fputc(d & 0x000000ff, fp);
|
fputc((d & 0x0000ff00) >> 8, fp);
|
fputc((d & 0x00ff0000) >> 16, fp);
|
fputc((d & 0xff000000) >> 24, fp);
|
}
|
|
static void writeword(FILE *fp, unsigned short d)
|
{
|
fputc(d & 0x00ff, fp);
|
fputc((d & 0xff00) >> 8, fp);
|
}
|
|
static void writebmp(unsigned int *rgb, int width, int height, int modulo)
|
{
|
FILE *fp;
|
int x, y;
|
int bytewidth = width * 3 + width % 4; // line width must be a multiple of 4 for BMPs
|
unsigned char *linebuf, *bak_linebuf;
|
unsigned int *tmprgb = rgb;
|
|
modulo /= 4;
|
|
if(!(fp = fopen("page.bmp", "wb"))) return;
|
|
linebuf = malloc(bytewidth);
|
|
fwrite("BM", 2, 1, fp);
|
|
writedword(fp, bytewidth * height + 54); // size
|
writedword(fp, 0); // reserved
|
writedword(fp, 0x36); // offset
|
writedword(fp, 0x28); // sizeof(struct BITMAPINFO)
|
writedword(fp, width);
|
writedword(fp, height);
|
writeword(fp, 1); // biPlanes
|
writeword(fp, 24); // bits
|
writedword(fp, 0); // compression
|
writedword(fp, 0); // size in bytes, may be zero for no compression
|
writedword(fp, 0); // pixels per meter
|
writedword(fp, 0); // pixels per meter
|
writedword(fp, 0); // biClrUsed
|
writedword(fp, 0); // biClrImportant
|
|
bak_linebuf = linebuf;
|
|
tmprgb += height * modulo;
|
|
// rgb data is stored in bottom-up format, pixel data is BGR
|
for(y = 0; y < height; y++) {
|
|
tmprgb -= modulo;
|
linebuf = bak_linebuf;
|
|
for(x = 0; x < width; x++) {
|
*linebuf++ = (unsigned char) (tmprgb[x] & 0x0000ff);
|
*linebuf++ = (unsigned char) ((tmprgb[x] & 0x00ff00) >> 8);
|
*linebuf++ = (unsigned char) ((tmprgb[x] & 0xff0000) >> 16);
|
}
|
|
fwrite(bak_linebuf, bytewidth, 1, fp);
|
}
|
|
free(bak_linebuf);
|
fclose(fp);
|
}
|
|
int main(int argc, char *argv[])
|
{
|
FPDF_DOCUMENT doc;
|
FPDF_PAGE page;
|
FPDF_BITMAP bm;
|
FPDF_LIBRARY_CONFIG config;
|
FS_MATRIX transform;
|
FS_RECTF rc;
|
float scale;
|
int pwidth, pheight, bwidth, bheight;
|
|
if(argc < 3) {
|
printf("Wrong args\n");
|
return 0;
|
}
|
|
memset(&config, 0, sizeof(config));
|
config.version = 2;
|
|
FPDF_InitLibraryWithConfig(&config);
|
|
if(!(doc = FPDF_LoadDocument((const char *) argv[1], NULL))) {
|
FPDF_DestroyLibrary();
|
printf("Failed to load PDF\n");
|
return 0;
|
}
|
|
scale = atof(argv[2]);
|
|
page = FPDF_LoadPage(doc, 0);
|
|
transform.a = scale;
|
transform.b = 0;
|
transform.c = 0;
|
transform.d = scale;
|
transform.e = 0;
|
transform.f = 0;
|
|
pwidth = (int) FPDF_GetPageWidth(page);
|
pheight = (int) FPDF_GetPageHeight(page);
|
|
bwidth = (int) ((float) pwidth * scale);
|
bheight = (int) ((float) pheight * scale);
|
|
printf("USING SCALE: %f PAGE SIZE: %d %d BITMAP SIZE: %d %d\n", scale, pwidth, pheight, bwidth, bheight);
|
|
bm = FPDFBitmap_Create(bwidth, bheight, 1);
|
|
FPDFBitmap_FillRect(bm, 0, 0, bwidth, bheight, 0xffffffff);
|
|
rc.left = 0;
|
rc.top = 0;
|
|
#if 0
|
// when using this code there is whitespace when downscaling and
|
// parts of the page are cut off when upscaling
|
rc.right = (float) bwidth;
|
rc.bottom = (float) bheight;
|
#else
|
// when using this code downscaling works fine but there is whitespace
|
// when upscaling
|
rc.right = (float) pwidth;
|
rc.bottom = (float) pheight;
|
#endif
|
|
FPDF_RenderPageBitmapWithMatrix(bm, page, &transform, &rc, 0);
|
|
writebmp(FPDFBitmap_GetBuffer(bm), bwidth, bheight, FPDFBitmap_GetStride(bm));
|
|
FPDFBitmap_Destroy(bm);
|
|
FPDF_ClosePage(page);
|
FPDF_CloseDocument(doc);
|
|
FPDF_DestroyLibrary();
|
|
return 0;
|
}
|
|
|