Suggesting to cancel the bountiable status (was Re: Re: Bug 687560 "Invalid PDF if /BP pdfmarks withnon-unique /_objdef")

"Igor V. Melichev" <[email protected]> Fri, 26 Nov 2004 09:20:44 +0300
Newsgroups gmane.comp.printing.ghostscript.patches
Message-ID <[email protected]>
Dear SaGS,

> This requirement does not make any sense. The above phrase refers to
> PDF_NAMECOLLISION_REBUILD and if you will search the bug report for the 3
> occurrences of "Compatibility:" you will see I wrote that Distiller
> implements PDF_NAMECOLLISION_KEEPOLD. (Note: Those conclusions should be
> considered guesses based on feeding files to Distiller or Jaws PDF Creator
> and looking at what comes out. All this stuff is not documented at all and I
> don't have privileged access to Adobe Systems or Global Graphics.)

Thus you try to define a feature, which is not defined by Adobe or Jaws.
I don't think that Artifex should implement it, unless you
bring an example of a popular PS writer, which refers to it.
If you have no such writer, I'll close the bug with "wontfix".

> The intent of PDF_NAMECOLLISION_REBUILD is to make all existing references
> (all kinds) to point to this new XObject, and "forget" the first one. Other

I consider this semantics as contradicting to programming traditions.
I definitely won't aprove to pass it to our codebase.
A right semantics is either an error or a variable-like behavior.

-----------------------------------

After this discussion I see that we have not enough reasons to
fix this bug, unless you bring new ones. 
Assuming that there is no more reasons, I consider
its "bountiable" status to be an Artifex's mistake.

I realise that the "bountiable" status encoraged you to work on it.
Since you worked on it, I'll ask administration about paying you half sum for "wontfix".
The "half" comes since you share the responsibility for opening this bug.
Let me know if it is OK.

Igor.

----- Original Message ----- 
From: "SaGS" <[email protected]>
To: "Igor V. Melichev" <[email protected]>; "gs-code-review" <[email protected]>
Sent: Thursday, November 25, 2004 11:40 PM
Subject: Re: [gs-code-review] Re: Bug 687560 "Invalid PDF if /BP pdfmarks withnon-unique /_objdef"


> ----- Original Message -----
> From: "Igor V. Melichev" <[email protected]>
> To: "SaGS" <[email protected]>; "gs-code-review"
> <[email protected]>
> Sent: Thursday, 25 November 2004 09:32
> Subject: [gs-code-review] Re: Bug 687560 "Invalid PDF if /BP pdfmarks
> withnon-unique /_objdef"
> 
> 
>> ...
>> > I chose to resolve each {OBJRef} to the MOST RECENT definition in
> execution order; "forward references" (= {OBJRef}
>> > with no preceding definition of that object) are resolved to the FIRST
> occurrence.
>>
>> 1. Please prove that this behavior is same as Adobe Distiller. Thank you.
> 
> This requirement does not make any sense. The above phrase refers to
> PDF_NAMECOLLISION_REBUILD and if you will search the bug report for the 3
> occurrences of "Compatibility:" you will see I wrote that Distiller
> implements PDF_NAMECOLLISION_KEEPOLD. (Note: Those conclusions should be
> considered guesses based on feeding files to Distiller or Jaws PDF Creator
> and looking at what comes out. All this stuff is not documented at all and I
> don't have privileged access to Adobe Systems or Global Graphics.)
> 
> A word about "I chose to": actually I don't see other reasonable choice. I
> like the idea of "dynamic scoping", particularly because it maximizes
> independence among objects.
> 
>>
>> 2. Now I see the reason for the "surgery". You need to put "x 0 R" into
> the output
>> PDF when the object ID=x is not yet created. However the function
> pdf_enter_substream
>> has the argument "bool reserve_object_id", which works exactly for this
> case with the value "false".
>> In this case the existing code calls pdf_reserve_object_id later.
>>
>> To resolve the "surgery", I suggest to do the folowing :
>>
>> 1. When we need to write out a reference to an undefined object,
>> create a fake object, and assign a new object id to it.
>>
>> 2. When the object is being defined later,
>> create another cos object with pdf_enter_substream,
>> drop the fake object with pdf_forget_resource,
>> and set the object id to the new object equal to the one from the fake
> object.
>>
> 
> Nope. The "surgery" is needed by PDF_NAMECOLLISION_REBUILD, which kicks in
> when THERE ALREADY ARE TOO MANY objects with ID=x (well, more exactly: one
> already exists and a second one is coming).
> 
> Let me explain again:
> 
>    [{OBJECT_A} ... /BP pdfmark
>    ... marking operators ...
>    [/EP pdfmark
>    ... some extra PostScript code ...
>    [{OBJECT_A} ... /BP pdfmark <- here kicks in one of
> PDF_NAMECOLLISION_REBUILD,
>                                   PDF_NAMECOLLISION_KEEPOLD, or
> PDF_NAMECOLLISION_BACKUP
>    ... (possibly other) marking operators ...
>    [/EP pdfmark
> 
> At the point I marked:
> - we already have a complete Form XObject (created by the first /BP)
> - this existing XObject must be registered in pdev->local_named_objects,
> otherwise it cannot be found during "... some extra PostScript code ..."
> - objects in pdev->local_named_objects MUST have IDs already assigned; this
> is required by pdf_replace_names()/ pdfmark_next_object() (in gdevpdfr.c)
> that process {OBJRefs} converting them to "n 0 Refs"; if objects have no
> number, we get "0 0 R" or "-1 0 R", which are invalid and fixing them later
> is impossible (there's no information about which object these are supposed
> to point to).
> - when the 2nd /BP appears, we must
>   (a) create a dictionary because we need to store the /Matrix etc.
> somewhere,
>   (b) create a stream for the very next PostScript (marking) operators to
> write into,
> so in fact we have to prepare a complete Form XObject.
> 
> The intent of PDF_NAMECOLLISION_REBUILD is to make all existing references
> (all kinds) to point to this new XObject, and "forget" the first one. Other
> way to express this: get in the same state we would be if the first XObject
> did not exist at all.
> 
> How do you find "reference to an undefined object" and "object is being
> defined later" fit here?
> 
> -------
> 
> If you can guarantee there are no "C-ptrs" pointing to the old cos_object_t
> structure (Note *), this old copy can be freed (logically and/or physically)
> after moving whatever needs to be preserved to the new copy, and we don't
> need cos_write_stream_redir()/ etc. (steps 2.1 .. 2.4 in your message dated
> November 4th). If there are "C-ptrs" to the old cos_stream_t, we must
> preserve the structure itself, so we need the "surgery" in order to link the
> old structure in the new cos_object_t's place and move the new contents to
> the old structure.
> 
> Another way to get rid of cos_dict_objects_write() is to move the stream's
> contents (with cos_stream_move_all()) inside /EP, not inside /BP. But this
> requires some place to store the information needed to locate the "old"
> cos_stream_t, including a stack for /NamespacePush and /NamespacePop. I
> consider this to be too involved.
> 
> 
> (Note *) excluding those that start_XObject() and functions it calls are
> supposed to handle: pointers from cos_object_t to its pdf_resource_t and
> vice-versa, and those used to link the pdf_resource_t on the resource chain
> and the cos_object_t into pdev->local_named_objects.
> 
> -------
> 
> I find there is another way to do as you say, but it is very involved and
> it's not worth the effort:
> 
> - In pdev->local_named_objects keep the "fake objects" exclusively (to be
> found by /PUT and {OBJRefs}), one fake object per distill-time name. These
> are never deleted/ replaced (but they can be "emptied" if necessary);
> - Create a structure parallel with pdev->local_named_objects to store the
> "real" objects; these are not stored in pdev->local_named_objects to be sure
> there won't be any "C-ptrs" to them so they can be deleted and replaced at
> any time without the need for "surgery";
> - At end-of-job/ NamespacePop time, cos_dict_objects_write() merges the
> "fake objects" (content added by /PUT) with the "real" objects (content
> coming mostly from marking operators) and writes the result to the output
> PDF.
> 
> 
> SaGS
>