Giter Club home page Giter Club logo

jipp's Introduction

CircleCI CodeCov Maven Central Core Docs PDL Docs Kotlin ktlint

JIPP: A Java-compatible IPP library

This project includes:

  • jipp-core is an IPP parser/builder for IPP packets.
  • jipp-pdls converts rasterized documents into common page description languages (PCLm and PWG-Raster).
  • jprint shows how jipp-core can be used to send a document to a printer.
  • jrender shows how jipp-pdl can be used to convert a PDF to PCLm or PWG-Raster.

jipp-core features:

  • Supports construction of IPP servers, clients, routers, gateways, etc.
  • Common operations and attributes available for use.
  • Can be extended to support new operations and attributes.
  • Can be used over any transport (typically HTTP).
  • Includes a pretty-printer for human-readable IPP packet display.
  • Kotlin users can access a type-safe packet building DSL

What could I do with this?

  • Scan and show available printers on your network to your users.
  • Implement an Android Print Service.
  • Test IPP clients or IPP printers in interesting ways.
  • Experiment with alternative IPP transports.
  • Implement a cloud-based print server or client.

The API is Java-compatible but implemented in Kotlin.

Usage

  1. Add the current version of JIPP to your project
dependencies {
    compile 'com.hp.jipp:jipp-core:0.7.15'
    compile 'com.hp.jipp:jipp-pdl:0.7.15' // Only needed if transforming PDLs
}
  1. Create an IppClientTransport or IppServerTransport (see example HttpIppClientTransport.java)
  2. Use the transport to send and receive IppPacket objects, e.g.:
URI uri = URI.create("http://192.168.1.100:631/ipp/print");
IppPacket printRequest = IppPacket.printJob(uri)
        .putOperationAttributes(documentFormat.of("application/pdf")))
        .build();
transport.sendData(uri, new IppPacketData(printRequest, new FileInputStream(inputFile)));

Sample Applications

jprint

Demonstrates a simple print engine. To run:

# build the app
./gradlew jprint:build

# unzip in the current directory
unzip -o ./sample/jprint/build/distributions/jprint-*.zip

# Use IPP to print a file to the supplied HTTP/IPP endpoint.
# (The printer must natively support the supplied file type.)
jprint-*/bin/jprint -p sample.pdf ipp://192.168.1.102:631/ipp/print

jrender

An example of rendering a PDF to PWG-Raster or PCLm. To run:

# build the app
./gradlew jrender:build

# unzip in the current directory
unzip -o ./sample/jrender/build/distributions/jrender-*.zip

# Convert a PDF-file to PWG-Raster.
jrender-*/bin/jrender sample.pdf sample.pwg

# Convert a PDF-file to PCLm.
jrender-*/bin/jrender sample.pdf sample.pclm

API Maturity

Until 1.0, APIs may still be changed in non-backwards-compatible ways. See HISTORY.md for more details.

Dependencies

jipp-core's only dependencies are JDK 8+ and the current Kotlin runtime.

Building

To build, run ./gradlew build.

A full build of this project requires python (2.x) and dot to generate dependency graphs.

jipp's People

Contributors

gladediviney avatar hpnavjot avatar hpsudip avatar neko-gg avatar peter-printix avatar psoreide avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jipp's Issues

Make Tag types more granular

At present a Tag can be injected almost anywhere since there is only one Tag type.

But there many are cases where only certain tags are legal:

  • Attribute Groups must begin with a delimiter tag
  • Empty attributes must be annotated with an out-of-band tag
  • Attribute types themselves must be accompanied by a value-describing tag (Integer, Octet-string, Character-string)

It would be good to constrain the functions that accept Tag objects to accept only the right sort of tag, e.g. DelimiterTag, OutOfBandTag, and ValueTag subclasses.

Allow integer-level access to all enums

For example, it should be possible to do a switch on Finishings codes, e.g.:

switch(finishing.code) {
case edgeStitch:
   break;
...
}

Currently this is not possible because something like Finishings.edgeStitch is only available as an Enum() object, which can't be compared via Java's switch statement.

Bad request sending printJob request

I'm trying IPP printing on Android, my printer is an Epson Workforce 3725. After successfully connecting via Wi-Fi Direct, I'm running:

final File file = new File(mContext.getFilesDir(), filename);

URI uri = URI.create("http://192.168.10.1:631/ipp/print");

IppPacket printRequest = new IppPacket(Operation.printJob, 125, AttributeGroup.groupOf(Tag.operationAttributes, printerUri.of(uri)));

IppClientTransport transport = new HttpIppClientTransport();
try {
    IppPacketData request = new IppPacketData(printRequest, new FileInputStream(file));
    IppPacketData response = transport.sendData(uri, request);
    
    Log.d("main", response.getPacket().prettyPrint(100, "  "));
} catch (IOException ex) {
    Log.e("main", "Error: "+ ex.toString());
}

File is PDF created with built-in Android library. I'm getting this error:

IppPacket(v=0x200, c=client-error-bad-request(1024), r=0x7d) {
      operation-attributes {
        attributes-charset = "utf-8" (charset),
        attributes-natural-language = "en" (naturalLanguage) } }

EDIT
Using sample application jprint from the command line I am able to print using LAN address (http://192.168.1.22:631/ipp/print instead of http://192.168.10.1:631/ipp/print), but the POST request is printed, not the actual file. It's like I was printing using port 9100.

Sample application

A sample command-line application could be supplied to assist users just getting started.

Implement number of copies

I'm trying to specify the number of copies to print, the problem is that I didn't find this attribute.

I am trying to accomplish something like this:

List<AttributeGroup> attributeGroups = new ArrayList<>();
		attributeGroups.add(
				groupOf(operationAttributes,
						attributesCharset.of("utf-8"),
						attributesNaturalLanguage.of("en"),
						printerUri.of(uri),
						documentFormat.of(format)));
		attributeGroups.add(
				groupOf(jobAttributes,
					      copies.of(2))
                                );

IppPacket printRequest = new IppPacket(IppPacket.DEFAULT_VERSION_NUMBER, Operation.printJob.getCode(), requestId, attributeGroups);

RenderablePage calculations are too rigid

Change the API to allow DPI to be specified at the RenderableDoc level, and for RenderablePage to potentially have its own calculation for determining pixel width. This will allow for more flexibility in client selection of pixel width, etc.

Unsupported-attributes

I getting error of unsupported-attributes with example

        IppPacket printRequest = new IppPacket(Operation.printJob, 1,  
                   groupOf(operationAttributes,
                        attributesCharset.of("utf-8"),
                        attributesNaturalLanguage.of("en"),
                        printerUri.of(uri),
                        requestingUserName.of("jprint"),
                        documentFormat.of("image/jpeg")
                    ),         
                    groupOf(jobAttributes,
                        media.of("isoA5_148x210"),
                        printQuality.of(quality)                            
                    )
        );

and i have question what is proper way to putt all important job atributes like: print quality, resolution, page size a5, a4 etc. I try with media.of("isoA5_148x210"), and media.of("iso_a5_148x210") but still that same unsupported-attributes.

And other question its ther way to put information for pritner without groupOf like int this example below

        var file = {
            "operation-attributes-tag":{
                "requesting-user-name": "User",
                "job-name": "Print Job",
                "document-format": "image/jpeg", // jpeg/png
            },
            "job-attributes-tag": {
                "media": "iso_a5_148x210mm",
                "print-quality": "high",
                "orientation-requested":"portrait"
            },
            version: "2.0",
            data: fileBuffer
        };

or style like from ippTool like down below:

    Print a test page using print-job
    {
The name of the test...
NAME "Print file using Print-Job"

The operation to use
OPERATION Print-Job

Attributes, starting in the operation group...
GROUP operation-attributes-tag
ATTR charset attributes-charset utf-8
ATTR language attributes-natural-language en
ATTR uri printer-uri $uri
ATTR name requesting-user-name $user
ATTR mimetype document-format image/jpeg

GROUP job-attributes-tag
ATTR integer copies 1
ATTR name media iso_a5_148x210mm
ATTR enum print-quality 4
ATTR collection media-col {
 US Letter plain paper from the "main" tray
	MEMBER collection media-size {
        MEMBER integer x-dimension 14800
	  MEMBER integer y-dimension 21000
	}
	MEMBER keyword media-source "main"
	MEMBER keyword media-type "stationery"
}

FILE $filename

What statuses are OK?
STATUS successful-ok
STATUS successful-ok-ignored-or-substituted-attributes

What attributes do we expect?
EXPECT job-id
EXPECT job-uri
   }

Sterilize APIs

  • Review all docs and make sure no classes or members are exposed public which should be private.
  • Make sure all remaining APIs have adequate javadoc

KeyValues sometimes aren't parsed from attributes

A locally created Attribute having KeyValues may not be properly extracted from an AttributeGroup in some circumstances.

Also the Attribute type for KeyValues should be KeyValuesType not KeyValueType.

Make it easier to encode attribute with out-of-band values

If you have a name only, it's not possible to create an "unknown" or other out-of-band attribute value unless you surround it with a fake type, e.g.

    attr(IntType(name).unknown())

It would be better to allow out-of-band Attributes to be created directly, perhaps:

    attr(Attribute.unknown(name))

Qestion: how to get resolution of Color

My printer send mi info about only resolution in black 600x600 but i know that is another resolution in color how to get it and how to set it? My rpitner have 600x600 dpi in black nad 9600x2400 in color 1pl

Add a MutableAttributeGroup

It is sometimes convenient to build up attribute groups gradually instead of declaring them all at once. So allow mutableGroupOf() with mutating accessors.

Better kotlin DSL attribute groups

This snippet:

ippPacket {
    operationAttributes {
        // add one
    }

    operationAttributes {
        // add two
    }
}

Adds two Tag.operationAttributes groups which is illegal. It should just concatenate more attributes with each operationAttributes section.

Don't use BufferedInputStream when parsing

Currently IppInputStream is defined as a subclass of DataInputStream(BufferedInputStream(inputStream)). The effect is to draw off an 8k buffer from inputStream, most of which won't be read as IPP packets are usually smaller. This makes it difficult to recover the remainder of the stream when it contains a document.

Compactify toString output for collection types

Collection types such as MediaCol contain many optional fields. But they all print in the `toString() representation:

MediaCol(mediaBackCoating=null, mediaBottomMargin=330, mediaColor=null, mediaFrontCoating=null, mediaGrain=null, mediaHoleCount=null, mediaInfo=null, mediaKey=null, mediaLeftMargin=330, mediaOrderCount=null, mediaPrePrinted=null, mediaRecycled=null, mediaRightMargin=330, mediaSize=MediaSize(xDimension=21590, yDimension=27940), mediaSizeName=null, mediaSource=main, mediaSourceProperties=null, mediaThickness=null, mediaTooth=null, mediaTopMargin=330, mediaType=stationery, mediaWeightMetric=null)

Consider overriding toString with a version that skips null fields.

Better debug output for types

Instead of

com.hp.jipp.encoding.KeywordType@5c084f9=job-state-reasons = [none]

we should see something like

KeywordType(job-state-reasons) = [none]

Update sample to get supported attributes

How to set media-size with x and y ? With this code bellow i getting unsuported attribute?

MediaCol.MediaSize mediaSize = new MediaCol.MediaSize(14800,21000);
MediaCol mediaType1 = new MediaCol();
mediaType1.setMediaLeftMargin(0);
mediaType1.setMediaRightMargin(0);
mediaType1.setMediaBottomMargin(0);
mediaType1.setMediaSize(mediaSize);
mediaType1.setMediaTopMargin(0);
mediaType1.setMediaType(new KeywordOrName(MediaType.photographic));

Exotic input streams cause parse errors

com.hp.jipp.util.ParseError: Value too short: expected 28 but got 25
	at com.hp.jipp.encoding.IppInputStream.readValueBytes$jipp_core(IppInputStream.kt:42)
	at com.hp.jipp.encoding.IppInputStream.readString$jipp_core(IppInputStream.kt:63)
	at com.hp.jipp.encoding.KeywordType$$special$$inlined$invoke$1.readValue(Codec.kt:55)
	at com.hp.jipp.encoding.AttributeGroup$Companion.readValue(AttributeGroup.kt:211)
	at com.hp.jipp.encoding.AttributeGroup$Companion.readNextValue(AttributeGroup.kt:230)

Caused by using read(byte[]) (which may well decide to return early without blocking for additional bytes) instead of readFully(byte[]) (which will not).

Make it easier to get attribute order correct

https://tools.ietf.org/html/rfc8011#section-4.1.4 specifies required ordering for attributes-charset, attributes-natural-language, *-uri and job-id attributes.

But groupOf, while flexible, allows you to toss any old order in there.

Let's add these to the DSL:

operationGroupOf("us-en", "utf-8", ...others)
uriOperationGroupOf("us-en", "utf-8", printerUri.of(uri), ...others)
jobOperationGroupOf("us-en", "utf-8", jobUri, jobId, ...others)

An error would be thrown if the "others" attributes were to contain attributes-charset, attributes-natural-language, or any out-of-order -uri attributes.

Make pretty printer more compact

Instead of

                       media-col-database = [
                         {
                           media-size = { x-dimension = 18415, y-dimension = 26670 },
                           media-top-margin = 330,
                           media-type = stationery },
                         {
                           media-size = { x-dimension = 18415, y-dimension = 26670 },

why not

                       media-col-database = [
                         { media-size = { x-dimension = 18415, y-dimension = 26670 },
                           media-top-margin = 330,
                           media-type = stationery },
                         { media-size = { x-dimension = 18415, y-dimension = 26670 },

Support ABNF types

These have snuck into several specs as Octet Strings with well-defined form. For example, https://ftp.pwg.org/pub/pwg/candidates/cs-ippjobprinterext3v10-20120727-5100.13.pdf defines several keys such as printer-output-tray.

JIPP can process these as "KeyValues" but this is unsatisfying because well-known keys and frequently well-known values exist, but neither keys nor values appear in as IANA defined terms. Manually retyping these into client/server code can lead to bugs.

It would be ideal to identify the relevant specs and where possible extract the acceptable fields and values wherever possible.

Default to IPP 2.2

Packets are built advertising IPP 1.1 by default. 2.2 should be the default.

How to transform a PDF to PCLm?

The sample code seems not to make use of any transformation.

Is there a way to update it to show how to create a RenderableDocument from a PDF?

Printer prints hundreds of pages with wired chars

I'm trying to print this simple PDF document from Android using this library, using my Epson Workforce 3520 via Wi-Fi Direct.

I'm connected to the printer and able to send documents to print. However, it's happening something really strange. Instead of printing one copy of my PDF, the printer is throwing out hundreds of pages with wired chars. They seem small chunks of data, and they get printed one for each page. The printer is definitively not interpreting the file I'm sending correctly.

Here is the code:

final File file = new File(mContext.getFilesDir(), filename);

URI uri = URI.create("http://192.168.10.1:631/ipp/print");

IppPacket printRequest = new IppPacket(Operation.printJob, 125, AttributeGroup.groupOf(Tag.operationAttributes, printerUri.of(uri)));

IppClientTransport transport = new HttpIppClientTransport();
try {
    IppPacketData request = new IppPacketData(printRequest, new FileInputStream(file));
    IppPacketData response = transport.sendData(uri, request);
    
    Log.d("main", response.getPacket().prettyPrint(100, "  "));
} catch (IOException ex) {
    Log.e("main", "Error: "+ ex.toString());
}

I've already tried sending documentFormat as application/octet-stream but nothing. Also tried text/plain and application/pdf, but I got document-format-not-supported error.

Also, I get the same strange behavior printing from jprint sample application from this repo.

Problem with margins

I have this sample of configuration:

            MediaCol.MediaSize mediaSize = new MediaCol.MediaSize(14800,21000);
            MediaCol mediaType1 = new MediaCol();
            mediaType1.setMediaLeftMargin(0);
            mediaType1.setMediaRightMargin(0);
            mediaType1.setMediaBottomMargin(0);
            mediaType1.setMediaSize(mediaSize);
            mediaType1.setMediaTopMargin(0);
            mediaType1.setMediaType(new KeywordOrName(MediaType.photographic));

            List<MediaCol> readyList = new ArrayList<>();
            readyList.add(mediaType1);
            IppPacket printRequest = new IppPacket(Operation.printJob, 1,
                    groupOf(operationAttributes,
                            attributesCharset.of("utf-8"),
                            attributesNaturalLanguage.of("en"),
                            printerUri.of(uri),
                            requestingUserName.of("jprint"),
                            documentFormat.of("image/jpeg")
                    ),
                    groupOf(jobAttributes,
                            Types.mediaCol.of(mediaType1),
                            Types.printScaling.of(scaling),
                            Types.printerKind.of(kind),
                            Types.media.of(Media.isoA5_148x210mm),
                            Types.printQuality.of(Integer.valueOf(quality))
                    )
            );

And if i print with scaling "fit" or "fill" i geting 4-8 mm margins.

PWG and PCLM Duplex cases not quite right

  1. In PWG pages are not rotated/flipped as requested
  2. PCLM and PWG pages are re-ordered according to WFDS specification, but tested printers don't actually require this.

How to add 'sides' job attribute?

Hi, I run the following code and the printer response with client-error-bad-request(1024) r=0x7b, is it some syntax error or just the printer does not support this attribute?

        val printRequest = IppPacket(
            Operation.printJob, 123,
            groupOf(
                operationAttributes,
                attributesCharset.of("utf-8"),
                attributesNaturalLanguage.of("en"),
                printerUri.of(uri),
                requestingUserName.of("jprint"),
                documentFormat.of("application/pdf")
            ),
            groupOf(
                jobAttributes,
                sides.of("two-sided-long-edge")
            )
        )
        val transport = HttpIppClientTransport()
        val request = IppPacketData(printRequest, FileInputStream(inputFile))
        val (packet) = transport.sendData(uri, request)

Allow multiple values only for 1-set-of types

Currently all AttributeType and Attribute objects support the storage of multiple values. This is not as per specification, since some items can be sets and others cannot. This encourages specification violations by allowing users to supply multiple values for an attribute type that doesn't support them.

To address this we would need separate types for single-value attributes (which could contain 0 or 1 values) and multi-value attributes (containing an ordered collection of 0 to n values, confusingly called "1setOf" in IPP specifications).

Remove static interface methods

Building for Android M results in

D8: Static interface methods are only supported starting with Android N (--min-api 24): com.hp.jipp.encoding.Attribute com.hp.jipp.encoding.Attribute.noValue(java.lang.String)

"of" should support Iterable

Currently the of functions only take List objects, but this is sometimes inconvenient when supplying a Set or Collection or Queue etc.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.