Commit cee2592ed1f1c8ac5ca3048c48ac082e47358a6b

Authored by Jay Berkenbilt
1 parent f31e526d

Change API/ABI and withdraw 4.2.0

4.2.0 was binary incompatible in spite of there being no deletions or
changes to any public methods.  As such, we have to bump the ABI and
are fixing some API breakage while we're at it.

Previous 4.3.0 target is now 5.1.0.
ChangeLog
  1 +2013-07-10 Jay Berkenbilt <ejb@ql.org>
  2 +
  3 + * 4.2.0 turned out to be binary incompatible on some platforms
  4 + even though there were no changes to the public API. Therefore
  5 + the 4.2.0 release has been withdrawn, and is being replaced with a
  6 + 5.0.0 release that acknowledges the ABI change and also removes
  7 + some problematic methods from the public API.
  8 +
  9 + * Remove methods from public API that were only intended to be
  10 + used by QPDFWriter and really didn't make sense to call from
  11 + anywhere else as they required internal knowledge that only
  12 + QPDFWriter had:
  13 + - QPDF::getLinearizedParts
  14 + - QPDF::generateHintStream
  15 + - QPDF::getObjectStreamData
  16 + - QPDF::getCompressibleObjGens
  17 + - QPDF::getCompressibleObjects
  18 +
1 19 2013-07-07 Jay Berkenbilt <ejb@ql.org>
2 20  
3   - * 4.2.0: release
  21 + * 4.2.0: release [withdrawn]
4 22  
5 23 * Ignore error case of a stream's decode parameters having invalid
6 24 length when there are no stream filters.
... ...
1   -4.3.0
  1 +5.1.0
2 2 =====
3 3  
  4 + * Figure out what about a3576a73593987b26cd3eff346f8f7c11f713cbd
  5 + broke binary compatibility.
  6 +
  7 + * Implement automated testing for binary compatibility and add to
  8 + release checklist.
  9 +
4 10 * Add method to push inheritable resources to a single page by
5 11 walking up and copying without overwrite. Above logic will also be
6 12 sufficient to fix the limitation in
... ... @@ -55,19 +61,6 @@
55 61  
56 62  
57 63  
58   -Next ABI change
59   -===============
60   -
61   - * Remove QPDF::getCompressibleObjects()
62   -
63   - * For public QPDF methods that are only public so QPDFWriter can
64   - call them, make them private and provide a nested caller class with
65   - QPDFWriter as a friend for access just like is being done now for
66   - some other methods. This will reduce the risk that future changes
67   - in the interface between QPDFWriter and QPDF will result in
68   - breaking ABI changes.
69   -
70   -
71 64 General
72 65 =======
73 66  
... ...
include/qpdf/QPDF.hh
... ... @@ -411,45 +411,6 @@ class QPDF
411 411 void optimize(std::map<int, int> const& object_stream_data,
412 412 bool allow_changes = true);
413 413  
414   - // For QPDFWriter:
415   -
416   - // Get lists of all objects in order according to the part of a
417   - // linearized file that they belong to.
418   - QPDF_DLL
419   - void getLinearizedParts(
420   - std::map<int, int> const& object_stream_data,
421   - std::vector<QPDFObjectHandle>& part4,
422   - std::vector<QPDFObjectHandle>& part6,
423   - std::vector<QPDFObjectHandle>& part7,
424   - std::vector<QPDFObjectHandle>& part8,
425   - std::vector<QPDFObjectHandle>& part9);
426   -
427   - QPDF_DLL
428   - void generateHintStream(std::map<int, QPDFXRefEntry> const& xref,
429   - std::map<int, qpdf_offset_t> const& lengths,
430   - std::map<int, int> const& obj_renumber,
431   - PointerHolder<Buffer>& hint_stream,
432   - int& S, int& O);
433   -
434   - // Map object to object stream that contains it
435   - QPDF_DLL
436   - void getObjectStreamData(std::map<int, int>&);
437   -
438   - // Get a list of objects that would be permitted in an object
439   - // stream.
440   - QPDF_DLL
441   - std::vector<QPDFObjGen> getCompressibleObjGens();
442   -
443   - // Deprecated: get a list of objects that would be permitted in an
444   - // object stream. This method is deprecated and will be removed.
445   - // It's incorrect because it disregards the generations of the
446   - // compressible objects, which can lead (and has lead) to bugs.
447   - // This method will throw an exception if any of the objects
448   - // returned have a generation of other than zero. Use
449   - // getCompressibleObjGens() instead.
450   - QPDF_DLL
451   - std::vector<int> getCompressibleObjects();
452   -
453 414 // Convenience routines for common functions. See also
454 415 // QPDFObjectHandle.hh for additional convenience routines.
455 416  
... ... @@ -504,6 +465,49 @@ class QPDF
504 465 QPDF_DLL
505 466 void removePage(QPDFObjectHandle page);
506 467  
  468 + // Writer class is restricted to QPDFWriter so that only it can
  469 + // call certain methods.
  470 + class Writer
  471 + {
  472 + friend class QPDFWriter;
  473 + private:
  474 +
  475 + static void getLinearizedParts(
  476 + QPDF& qpdf,
  477 + std::map<int, int> const& object_stream_data,
  478 + std::vector<QPDFObjectHandle>& part4,
  479 + std::vector<QPDFObjectHandle>& part6,
  480 + std::vector<QPDFObjectHandle>& part7,
  481 + std::vector<QPDFObjectHandle>& part8,
  482 + std::vector<QPDFObjectHandle>& part9)
  483 + {
  484 + qpdf.getLinearizedParts(object_stream_data,
  485 + part4, part6, part7, part8, part9);
  486 + }
  487 +
  488 + static void generateHintStream(
  489 + QPDF& qpdf,
  490 + std::map<int, QPDFXRefEntry> const& xref,
  491 + std::map<int, qpdf_offset_t> const& lengths,
  492 + std::map<int, int> const& obj_renumber,
  493 + PointerHolder<Buffer>& hint_stream,
  494 + int& S, int& O)
  495 + {
  496 + return qpdf.generateHintStream(xref, lengths, obj_renumber,
  497 + hint_stream, S, O);
  498 + }
  499 +
  500 + static void getObjectStreamData(QPDF& qpdf, std::map<int, int>& omap)
  501 + {
  502 + qpdf.getObjectStreamData(omap);
  503 + }
  504 +
  505 + static std::vector<QPDFObjGen> getCompressibleObjGens(QPDF& qpdf)
  506 + {
  507 + return qpdf.getCompressibleObjGens();
  508 + }
  509 + };
  510 +
507 511 // Resolver class is restricted to QPDFObjectHandle so that only
508 512 // it can resolve indirect references.
509 513 class Resolver
... ... @@ -635,6 +639,31 @@ class QPDF
635 639 QPDFObjectHandle dict,
636 640 Pipeline* pipeline);
637 641  
  642 + // For QPDFWriter:
  643 +
  644 + // Get lists of all objects in order according to the part of a
  645 + // linearized file that they belong to.
  646 + void getLinearizedParts(
  647 + std::map<int, int> const& object_stream_data,
  648 + std::vector<QPDFObjectHandle>& part4,
  649 + std::vector<QPDFObjectHandle>& part6,
  650 + std::vector<QPDFObjectHandle>& part7,
  651 + std::vector<QPDFObjectHandle>& part8,
  652 + std::vector<QPDFObjectHandle>& part9);
  653 +
  654 + void generateHintStream(std::map<int, QPDFXRefEntry> const& xref,
  655 + std::map<int, qpdf_offset_t> const& lengths,
  656 + std::map<int, int> const& obj_renumber,
  657 + PointerHolder<Buffer>& hint_stream,
  658 + int& S, int& O);
  659 +
  660 + // Map object to object stream that contains it
  661 + void getObjectStreamData(std::map<int, int>&);
  662 +
  663 + // Get a list of objects that would be permitted in an object
  664 + // stream.
  665 + std::vector<QPDFObjGen> getCompressibleObjGens();
  666 +
638 667 // methods to support page handling
639 668  
640 669 void getAllPagesInternal(QPDFObjectHandle cur_pages,
... ...
libqpdf/QPDF.cc
... ... @@ -1952,30 +1952,6 @@ QPDF::getObjectStreamData(std::map&lt;int, int&gt;&amp; omap)
1952 1952 }
1953 1953 }
1954 1954  
1955   -std::vector<int>
1956   -QPDF::getCompressibleObjects()
1957   -{
1958   - std::vector<QPDFObjGen> objects = getCompressibleObjGens();
1959   - std::vector<int> result;
1960   - for (std::vector<QPDFObjGen>::iterator iter = objects.begin();
1961   - iter != objects.end(); ++iter)
1962   - {
1963   - if ((*iter).getGen() != 0)
1964   - {
1965   - throw std::logic_error(
1966   - "QPDF::getCompressibleObjects() would return an object ID"
1967   - " for an object with generation != 0. Use"
1968   - " QPDF::getCompressibleObjGens() instead."
1969   - " See comments in QPDF.hh.");
1970   - }
1971   - else
1972   - {
1973   - result.push_back((*iter).getObj());
1974   - }
1975   - }
1976   - return result;
1977   -}
1978   -
1979 1955 std::vector<QPDFObjGen>
1980 1956 QPDF::getCompressibleObjGens()
1981 1957 {
... ...
libqpdf/QPDFWriter.cc
... ... @@ -1913,7 +1913,7 @@ QPDFWriter::preserveObjectStreams()
1913 1913 // must have generation 0 because the PDF spec does not provide
1914 1914 // any way to do otherwise.
1915 1915 std::map<int, int> omap;
1916   - this->pdf.getObjectStreamData(omap);
  1916 + QPDF::Writer::getObjectStreamData(this->pdf, omap);
1917 1917 for (std::map<int, int>::iterator iter = omap.begin();
1918 1918 iter != omap.end(); ++iter)
1919 1919 {
... ... @@ -1936,7 +1936,7 @@ QPDFWriter::generateObjectStreams()
1936 1936 // This code doesn't do anything with /Extends.
1937 1937  
1938 1938 std::vector<QPDFObjGen> const& eligible =
1939   - this->pdf.getCompressibleObjGens();
  1939 + QPDF::Writer::getCompressibleObjGens(this->pdf);
1940 1940 unsigned int n_object_streams = (eligible.size() + 99) / 100;
1941 1941 unsigned int n_per = eligible.size() / n_object_streams;
1942 1942 if (n_per * n_object_streams < eligible.size())
... ... @@ -2339,8 +2339,8 @@ QPDFWriter::writeHintStream(int hint_id)
2339 2339 PointerHolder<Buffer> hint_buffer;
2340 2340 int S = 0;
2341 2341 int O = 0;
2342   - pdf.generateHintStream(
2343   - this->xref, this->lengths, this->obj_renumber_no_gen,
  2342 + QPDF::Writer::generateHintStream(
  2343 + this->pdf, this->xref, this->lengths, this->obj_renumber_no_gen,
2344 2344 hint_buffer, S, O);
2345 2345  
2346 2346 openObject(hint_id);
... ... @@ -2610,8 +2610,9 @@ QPDFWriter::writeLinearized()
2610 2610 std::vector<QPDFObjectHandle> part7;
2611 2611 std::vector<QPDFObjectHandle> part8;
2612 2612 std::vector<QPDFObjectHandle> part9;
2613   - pdf.getLinearizedParts(this->object_to_object_stream_no_gen,
2614   - part4, part6, part7, part8, part9);
  2613 + QPDF::Writer::getLinearizedParts(
  2614 + this->pdf, this->object_to_object_stream_no_gen,
  2615 + part4, part6, part7, part8, part9);
2615 2616  
2616 2617 // Object number sequence:
2617 2618 //
... ...