2012-09-30 23 views
11

Tomé el ejemplo PDF mínimo en la especificación PDF desde PDF Specification, lo copié a NotePad, renombré el archivo para tener la extensión .pdf.Ejemplo PDF mínimo en la especificación PDF

Puedo abrirlo con otro visor de PDF (PDF-XChange, SumatraPDF, MuPDF). Pero cuando lo abro con Adobe Reader, dice que el archivo está roto.

No estoy seguro si otros usuarios tratan este archivo "roto" como un archivo en blanco o no.

Se supone que el archivo muestra una página en blanco, ya que es un ejemplo mínimo.

De hecho, modifico el ejemplo mínimo. Porque cuando lo copio desde la especificación de PDF al bloc de notas, y abro el archivo .txt con un editor hexadecimal, veo una nueva línea en el archivo .txt y obtengo 2 espacios. Por ejemplo,

1 0 obj 
<< /Type /Catalog 

me da (en Hex Editor)

1 0 obj << /Type /Catalog 

que es (en valores hexadecimales)

31 20 30 20 6F 62 6A 0D 0A 3C 3C 20 2F 54 79 70 
65 20 2F 43 61 74 61 6C 6F 67 

Los 2 espacios entre j y < son 0D 0A.

Por lo tanto, no hago nuevas líneas en el Bloc de notas, y modifico los valores en la parte xref.

A continuación se muestra el código completo.

¿Sabes qué hay de malo en este ejemplo? ¿Por qué Adobe Reader dice que está roto? ¿Esto es porque di los valores incorrectos en xref?

%PDF-1.4 1 0 obj << /Type /Catalog /Outlines 2 0 R /Pages 3 0 R >> endobj 2 0 obj << /Type Outlines /Count 0 >> endobj 3 0 obj << /Type /Pages /Kids [4 0 R] /Count 1 >> endobj 4 0 obj << /Type /Page /Parent 3 0 R /MediaBox [0 0 612 792] /Contents 5 0 R /Resources << /ProcSet 6 0 R >> >> endobj 5 0 obj << /Length 35 >> stream … Page-marking operators … endstream endobj 6 0 obj [/PDF] endobj xref 0 7 0000000000 65535 f 0000000009 00000 n 0000000074 00000 n 0000000119 00000 n 0000000176 00000 n 0000000295 00000 n 0000000373 00000 n trailer << /Size 7 /Root 1 0 R >> startxref 395 %%EOF 

Respuesta

16

Primero: cuando 'copiado' el ejemplo de la especificación PDF, muy probablemente un par de cosas sucedió que hizo que su copia a no funcionar como se espera:

  • ... no lo hiciste 't' copy 'volviendo a escribir el ejemplo en un editor de texto, pero
  • ... usaste copy'n'paste, usando un PDF como archivo de origen.

Dependiendo de su editor de texto, ese método probablemente causó que la conversión de la convención de nueva línea cambiara de [cr] + [lf] a [cr] o viceversa. Esto a su vez significa que los números de desplazamiento de bytes en el objeto 'tabla de contenidos' (la tabla 'xref') ya no son válidos.

Otro problema con el código fuente PDF informados es que no hace ahora contiene saltos de línea en absoluto . Algunos espectadores pueden ser capaces de analizar silenciosamente la cosa, pero no todos lo son. Y ciertamente va en contra de la especificación, porque de acuerdo con la especificación, en el capítulo 7.5.2 está claramente explicado que

"La primera línea de un archivo PDF debe ser un encabezado compuesto por los 5 caracteres% PDF - seguido de un número de versión del formulario 1.N, donde N es un dígito entre 0 y 7.

Su encabezado infringe esa regla.

Además, el 'arroyo' en 5 0 obj no es ningún código PDF válida, es simplemente el texto de marcador de posición (… Page-marking operators …). Algunos espectadores pueden estar inclinados cuando se encuentran con esa "basura".

Por último, su startxref valor no era el correcto.

Así que aquí hay un archivo que funciona. Reparé en un editor de texto, y pongo el código original como un comentario después de la %%EOF para la comparación y referencia:

%PDF-1.4 
1 0 obj 
<< /Type /Catalog /Outlines 2 0 R /Pages 3 0 R >> 
endobj 
2 0 obj 
<< /Type Outlines /Count 0 >> 
endobj 
3 0 obj 
<< /Type /Pages /Kids [4 0 R] /Count 1 >> 
endobj 
4 0 obj 
<< /Type /Page /Parent 3 0 R /MediaBox [0 0 612 792] /Contents 5 0 R /Resources << /ProcSet 6 0 R >> >> 
endobj 
5 0 obj 
<< /Length 35 >> 
stream 
… Page-marking operators … 
endstream 
endobj 
6 0 obj 
[/PDF] 
endobj 
xref 
0 7 
0000000000 65535 f 
0000000009 00000 n 
0000000074 00000 n 
0000000119 00000 n 
0000000176 00000 n 
0000000295 00000 n 
0000000376 00000 n 
trailer 
<< /Size 7 /Root 1 0 R >> 
startxref 
394 
%%EOF 

%% %PDF-1.4 1 0 obj << /Type /Catalog /Outlines 2 0 R /Pages 3 0 R >> endobj 2 0 obj << /Type Outlines /Count 0 >> endobj 3 0 obj << /Type /Pages /Kids [4 0 R] /Count 1 >> endobj 4 0 obj << /Type /Page /Parent 3 0 R /MediaBox [0 0 612 792] /Contents 5 0 R /Resources << /ProcSet 6 0 R >> >> endobj 5 0 obj << /Length 35 >> stream … Page-marking operators … endstream endobj 6 0 obj [/PDF] endobj xref 0 7 0000000000 65535 f 0000000009 00000 n 0000000074 00000 n 0000000119 00000 n 0000000176 00000 n 0000000295 00000 n 0000000373 00000 n trailer << /Size 7 /Root 1 0 R >> startxref 395 
+0

Gracias Kurt, pero ¿por qué el valor de startxref es 394, no 396. ¿No es este valor debería ser el desplazamiento de bytes del carácter 'x' en 'xref' en este archivo? Es 396 en un editor hexadecimal. Pero con 396, el archivo se rompe y 394 funcionan. No sé el motivo. – user565739

+0

@ user565739: Debe ejecutar 'dd bs = 1 skip = 394 if = this.pdf'. Eso significa que ha omitido los primeros 394 bytes al descargar el archivo. Ahora la salida debería comenzar con 'xref' en una línea por sí mismo. –

+0

Cuando copié/pegué esto, tuve que cambiar el carácter único "..." alrededor de "Operadores de marcado de página" a los tres caracteres "..." y el startxref de 394 a 398. Sospecho que cuando copié/pegué el único personaje "..." fue mordido. Al expandir a tres, el individuo "." en cualquier lado de la secuencia, eso agregó otros 4 bytes que me movieron a 398 desde 394 para el inicio de la tabla xref. – Pat