Compter le nombre de pages d'un fichier pdf

Contenu du snippet

Ce petit code source permet de compter le nombre de pages dans un fichier PDF.
Fonctionne au moins avec les PDF jusqu'au 1.4

les spécifications 1.5 voient entrer la compression de la table XRef... du coup, pour ce simple comptage, le code se voit allongé de deux a trois fois sa taille actuelle, d'après mes premières estimations.

vu que j'ai écrit ce code rapidement, pour un cadre précis, avec des fichiers 1.4...

Source / Exemple :


#if defined(WIN32)
	#define _CRT_SECURE_NO_WARNINGS
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int CountPDFPage(char *Fichier) {
	FILE *pdf;
	unsigned int count = 0;
	int offset;
	int len;
	int i;
	int refCount;
	char *p;
	char buf[1024];
	unsigned int *XRef;
	if ((pdf = fopen(Fichier, "rb")) == NULL) {
		printf("Impossible d'ouvrir le fichier PDF.\n");
		return -1;
	}

	fread(buf, 1, 5, pdf);
	if (strncmp(buf, "%PDF-", 5)) {
		printf("fichier non PDF.\n");
		return -2;
	}

	fseek(pdf, 0, SEEK_END);	
	offset = ftell(pdf)-60;
	fseek(pdf, offset, SEEK_SET);
	len = fread(buf, 1, 60, pdf);
	if (len!=60) {
		printf("fichier PDF corrompu\n");
		return -3;
	}

	buf[60] = 0;
	for(;;) {
		len = strlen(buf);
		if (len==60)
			break;
		else
			buf[len] = 32;
	}

	p = strstr(buf, "startxref");
	if (p==0) {
		printf("Erreur dans l'analyse du pdf. Impossible de trouver le StartXRef\n");
		return -4;			
	}
	
	p+=10;
	while (*p==32 || *p==10 || *p==13) p++;
	offset = atoi(p);
	if (offset<=0) {
		printf("Erreur dans l'analyse du pdf. StartXRef==%d\n", offset);
		return -5;
	}
	fseek(pdf, offset, SEEK_SET);
	
	/* On récupère le nombre d'entree de la XRef */
	fread(buf, 1, 40, pdf);	

	if (strncmp(buf, "xref", 4)) {
		printf("XRef incompatible. Peut être s'agit il d'un fichier PDF 1.5 ou superieur\n");
		return -6;
	}

	p=buf+4;
	while (*p==32 || *p==10 || *p==13) p++;
	while (*p>='0' && *p<='9') p++;
	while (*p==32) p++;

	refCount = atoi(p);
	if (refCount<=0) {
		printf("Erreur dans l'analyse du pdf. XRef==%d\n", refCount);
		return -7;
	}

	/* On va conserver la XRef en memoire. */
	XRef = malloc(sizeof(unsigned int)*--refCount);
	fseek(pdf, offset+32, SEEK_SET);
	for (i=0; i<refCount;) {
		len = fread(buf, 1, 1024, pdf);
		for(p=buf; i<refCount && p<(buf+len); p+=20) {
			XRef[i] = atoi(p);
			i++;
		}
	}

	/* Pour chaque object de la XRef... */
	for (i=0; i<refCount; i++) {
		fseek(pdf, XRef[i], SEEK_SET);	
		fread(buf, 1, 1024, pdf);
		p = strstr(buf, "/Type ");
		if (p) {
			if (strncmp(p, "/Type /Pages", 12))
				break; /* Seuls les /Pages nous interessent... */
			p = strstr(buf, ">>");
			if (p) 

  • p=0; /* Permet de ne pas tenir compte du 'trop-lu' du fichier */
/* Un fichier PDF peut contenir n groupes de pages. */ /* Seul l'element racine nous interesse : celui qui n'a pas de Parent */ if (strstr(buf, "/Parent ") == NULL) { p = strstr(buf, "/Count "); if (p) { count = atoi(p+7); /* Voila notre nombre de pages */ break; } } } } free(XRef); fclose(pdf); return count; } int main(int argc, char *argv[]) { int rc; if (argc!=2) { printf("Compte le nombre de pages d'un fichier PDF dont le chemin est donne en parametre.\n"); return 1; } rc = CountPDFPage(argv[1]); if (rc>0) { printf("%d\n", rc); return 0; } printf("%d\n", rc); return rc; }

Conclusion :


Rien de bien sorcier, mais outil bien utile au quotidien (enfin, dans mon quotidien en tous cas)

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.