Soyez le premier à donner votre avis sur cette source.
Snippet vu 8 749 fois - Téléchargée 21 fois
#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)
14 févr. 2012 à 11:48
14 févr. 2012 à 11:22
c'est normalement corrigé, plus bavard et plus les pdf mieux controlés.
Merci pour ces tests rapides et efficaces.
14 févr. 2012 à 10:39
toto.c: In function ‘CountPDFPage’:
toto.c:48:32: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
toto.c:48:48: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] (p et buf étant de même type (char*), les cast en unsigned int, sont-ils nécessaires pour effectuer "p < buf" ?)
toto.c:11:16: warning: variable ‘len’ set but not used [-Wunused-but-set-variable] (ligne 47, len est remplie mais jamais utilisé, peut être p<(buf+len); plutôt que p<(buf+1024) ?)
Autre question:
- Pourquoi avoir "casté" le retour du malloc ligne 44 ? En C, ce n'est pas nécessaire (uniquement en C++).- refCount atoi(p)-1;> Peut être tester le atoi(p) avant de faire un -1 dans un unsigned ? (Chez moi le atoi(p) renvoie 0 et j'ai alors une valeur de refCount gigantesque, d'où mon segfault).
>> les xref compressées que proposent les specs pdf 1.5 ne sont pas prises en compte, ca peut etre une evolution a prévoir.
Y aurait-il un moyen de voir si le fichier est compressé et avertir l'utilisateur plutôt qu'un segfault ?
En tout cas merci pour les modifications, c'est le genre de petit outil dont je n'ai pas encore l'utilité, mais que je vais garder sous le coude !
14 févr. 2012 à 08:44
Je cible aussi un systeme unix, avec cet outil, mes settings semblent etre plus laxistes que les tiens...
Je mets de coté cette -W -Wall pratique
Je m'en sert au boulot, dans des chaines de traitement (je sais donc que j'ai des pdf en entrée)
les xref compressées que proposent les specs pdf 1.5 ne sont pas prises en compte, ca peut etre une evolution a prévoir.
quand au fait que le fichier ne soit pas un pdf, il ne se passera pas grand chose, on ne trouvera pas de startxref en fin de fichier, so...
j'ai ajouté un test supplémentaire néanmoins
13 févr. 2012 à 17:24
J'ai néanmoins quelques petit soucis:
- Pourrais-tu vérifier le type mime ? Si l'on met un fichier qui n'est pas de type pdf, que se passe-t-il ?
- Chez moi, ton binaire plante (Arch Linux + gcc 4.6).
gdb --args ./a.out monpdf.pdf
Reading symbols from /tmp/a.out...done.
gdb$ r
Program received signal SIGSEGV, Segmentation fault.
0x00000000004009c7 in CountPDFPage (Fichier=0x7fffffffe358 "monpdf.pdf") at toto.c:47
47 { XRef[i] = atoi(p);
gdb$ bt
#0 0x00000000004009c7 in CountPDFPage (Fichier=0x7fffffffe358 "monpdf.pdf") at toto.c:47
#1 0x0000000000400b7f in main (argc=2, argv=0x7fffffffdf08) at toto.c:88
gdb$ quit
- J'ai *beaucoup* de warning à la compilation.
gcc -W -Wall -ansi -pedantic toto.c -g
toto.c: In function ‘CountPDFPage’:
toto.c:28:9: warning: pointer targets in assignment differ in signedness [-Wpointer-sign]
toto.c:28:3: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
toto.c:32:5: warning: pointer targets in passing argument 1 of ‘atoi’ differ in signedness [-Wpointer-sign]
/usr/include/stdlib.h:148:12: note: expected ‘const char *’ but argument is of type ‘unsigned char *’
toto.c:36:7: warning: pointer targets in assignment differ in signedness [-Wpointer-sign]
toto.c:39:5: warning: pointer targets in passing argument 1 of ‘atoi’ differ in signedness [-Wpointer-sign]
/usr/include/stdlib.h:148:12: note: expected ‘const char *’ but argument is of type ‘unsigned char *’
toto.c:46:12: warning: pointer targets in assignment differ in signedness [-Wpointer-sign]
toto.c:46:32: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
toto.c:46:48: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
toto.c:47:7: warning: pointer targets in passing argument 1 of ‘atoi’ differ in signedness [-Wpointer-sign]
/usr/include/stdlib.h:148:12: note: expected ‘const char *’ but argument is of type ‘unsigned char *’
toto.c:56:13: warning: pointer targets in assignment differ in signedness [-Wpointer-sign]
toto.c:56:7: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
toto.c:58:9: warning: pointer targets in passing argument 1 of ‘strncmp’ differ in signedness [-Wpointer-sign]
/usr/include/string.h:146:12: note: expected ‘const char *’ but argument is of type ‘unsigned char *’
toto.c:60:15: warning: pointer targets in assignment differ in signedness [-Wpointer-sign]
toto.c:60:9: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
toto.c:66:17: warning: pointer targets in assignment differ in signedness [-Wpointer-sign]
toto.c:66:11: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
toto.c:68:13: warning: pointer targets in passing argument 1 of ‘atoi’ differ in signedness [-Wpointer-sign]
/usr/include/stdlib.h:148:12: note: expected ‘const char *’ but argument is of type ‘unsigned char *’
toto.c:13:16: warning: variable ‘len’ set but not used [-Wunused-but-set-variable]
toto.c: At top level:
toto.c:80:5: warning: first argument of ‘main’ should be ‘int’ [-Wmain]
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.