1 // Copyright 2019 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4 5 //go:generate go run gen.go
6 7 // Package ccitt implements a CCITT (fax) image decoder.
8 package ccitt
9 10 import (
11 "encoding/binary"
12 "errors"
13 "image"
14 "io"
15 "math/bits"
16 )
17 18 var (
19 errIncompleteCode = errors.New("ccitt: incomplete code")
20 errInvalidBounds = errors.New("ccitt: invalid bounds")
21 errInvalidCode = errors.New("ccitt: invalid code")
22 errInvalidMode = errors.New("ccitt: invalid mode")
23 errInvalidOffset = errors.New("ccitt: invalid offset")
24 errMissingEOL = errors.New("ccitt: missing End-of-Line")
25 errRunLengthOverflowsWidth = errors.New("ccitt: run length overflows width")
26 errRunLengthTooLong = errors.New("ccitt: run length too long")
27 errUnsupportedMode = errors.New("ccitt: unsupported mode")
28 errUnsupportedSubFormat = errors.New("ccitt: unsupported sub-format")
29 errUnsupportedWidth = errors.New("ccitt: unsupported width")
30 )
31 32 // Order specifies the bit ordering in a CCITT data stream.
33 type Order uint32
34 35 const (
36 // LSB means Least Significant Bits first.
37 LSB Order = iota
38 // MSB means Most Significant Bits first.
39 MSB
40 )
41 42 // SubFormat represents that the CCITT format consists of a number of
43 // sub-formats. Decoding or encoding a CCITT data stream requires knowing the
44 // sub-format context. It is not represented in the data stream per se.
45 type SubFormat uint32
46 47 const (
48 Group3 SubFormat = iota
49 Group4
50 )
51 52 // AutoDetectHeight is passed as the height argument to NewReader to indicate
53 // that the image height (the number of rows) is not known in advance.
54 const AutoDetectHeight = -1
55 56 // Options are optional parameters.
57 type Options struct {
58 // Align means that some variable-bit-width codes are byte-aligned.
59 Align bool
60 // Invert means that black is the 1 bit or 0xFF byte, and white is 0.
61 Invert bool
62 }
63 64 // maxWidth is the maximum (inclusive) supported width. This is a limitation of
65 // this implementation, to guard against integer overflow, and not anything
66 // inherent to the CCITT format.
67 const maxWidth = 1 << 20
68 69 func invertBytes(b []byte) {
70 for i, c := range b {
71 b[i] = ^c
72 }
73 }
74 75 func reverseBitsWithinBytes(b []byte) {
76 for i, c := range b {
77 b[i] = bits.Reverse8(c)
78 }
79 }
80 81 // highBits writes to dst (1 bit per pixel, most significant bit first) the
82 // high (0x80) bits from src (1 byte per pixel). It returns the number of bytes
83 // written and read such that dst[:d] is the packed form of src[:s].
84 //
85 // For example, if src starts with the 8 bytes [0x7D, 0x7E, 0x7F, 0x80, 0x81,
86 // 0x82, 0x00, 0xFF] then 0x1D will be written to dst[0].
87 //
88 // If src has (8 * len(dst)) or more bytes then only len(dst) bytes are
89 // written, (8 * len(dst)) bytes are read, and invert is ignored.
90 //
91 // Otherwise, if len(src) is not a multiple of 8 then the final byte written to
92 // dst is padded with 1 bits (if invert is true) or 0 bits. If inverted, the 1s
93 // are typically temporary, e.g. they will be flipped back to 0s by an
94 // invertBytes call in the highBits caller, reader.Read.
95 func highBits(dst []byte, src []byte, invert bool) (d int, s int) {
96 // Pack as many complete groups of 8 src bytes as we can.
97 n := len(src) / 8
98 if n > len(dst) {
99 n = len(dst)
100 }
101 dstN := dst[:n]
102 for i := range dstN {
103 src8 := src[i*8 : i*8+8]
104 dstN[i] = ((src8[0] & 0x80) >> 0) |
105 ((src8[1] & 0x80) >> 1) |
106 ((src8[2] & 0x80) >> 2) |
107 ((src8[3] & 0x80) >> 3) |
108 ((src8[4] & 0x80) >> 4) |
109 ((src8[5] & 0x80) >> 5) |
110 ((src8[6] & 0x80) >> 6) |
111 ((src8[7] & 0x80) >> 7)
112 }
113 d, s = n, 8*n
114 dst, src = dst[d:], src[s:]
115 116 // Pack up to 7 remaining src bytes, if there's room in dst.
117 if (len(dst) > 0) && (len(src) > 0) {
118 dstByte := byte(0)
119 if invert {
120 dstByte = 0xFF >> uint(len(src))
121 }
122 for n, srcByte := range src {
123 dstByte |= (srcByte & 0x80) >> uint(n)
124 }
125 dst[0] = dstByte
126 d, s = d+1, s+len(src)
127 }
128 return d, s
129 }
130 131 type bitReader struct {
132 r io.Reader
133 134 // readErr is the error returned from the most recent r.Read call. As the
135 // io.Reader documentation says, when r.Read returns (n, err), "always
136 // process the n > 0 bytes returned before considering the error err".
137 readErr error
138 139 // order is whether to process r's bytes LSB first or MSB first.
140 order Order
141 142 // The high nBits bits of the bits field hold upcoming bits in MSB order.
143 bits uint64
144 nBits uint32
145 146 // bytes[br:bw] holds bytes read from r but not yet loaded into bits.
147 br uint32
148 bw uint32
149 bytes [1024]uint8
150 }
151 152 func (b *bitReader) alignToByteBoundary() {
153 n := b.nBits & 7
154 b.bits <<= n
155 b.nBits -= n
156 }
157 158 // nextBitMaxNBits is the maximum possible value of bitReader.nBits after a
159 // bitReader.nextBit call, provided that bitReader.nBits was not more than this
160 // value before that call.
161 //
162 // Note that the decode function can unread bits, which can temporarily set the
163 // bitReader.nBits value above nextBitMaxNBits.
164 const nextBitMaxNBits = 31
165 166 func (b *bitReader) nextBit() (uint64, error) {
167 for {
168 if b.nBits > 0 {
169 bit := b.bits >> 63
170 b.bits <<= 1
171 b.nBits--
172 return bit, nil
173 }
174 175 if available := b.bw - b.br; available >= 4 {
176 // Read 32 bits, even though b.bits is a uint64, since the decode
177 // function may need to unread up to maxCodeLength bits, putting
178 // them back in the remaining (64 - 32) bits. TestMaxCodeLength
179 // checks that the generated maxCodeLength constant fits.
180 //
181 // If changing the Uint32 call, also change nextBitMaxNBits.
182 b.bits = uint64(binary.BigEndian.Uint32(b.bytes[b.br:])) << 32
183 b.br += 4
184 b.nBits = 32
185 continue
186 } else if available > 0 {
187 b.bits = uint64(b.bytes[b.br]) << (7 * 8)
188 b.br++
189 b.nBits = 8
190 continue
191 }
192 193 if b.readErr != nil {
194 return 0, b.readErr
195 }
196 197 n, err := b.r.Read(b.bytes[:])
198 b.br = 0
199 b.bw = uint32(n)
200 b.readErr = err
201 202 if b.order != MSB {
203 reverseBitsWithinBytes(b.bytes[:b.bw])
204 }
205 }
206 }
207 208 func decode(b *bitReader, decodeTable [][2]int16) (uint32, error) {
209 nBitsRead, bitsRead, state := uint32(0), uint64(0), int32(1)
210 for {
211 bit, err := b.nextBit()
212 if err != nil {
213 if err == io.EOF {
214 err = errIncompleteCode
215 }
216 return 0, err
217 }
218 bitsRead |= bit << (63 - nBitsRead)
219 nBitsRead++
220 221 // The "&1" is redundant, but can eliminate a bounds check.
222 state = int32(decodeTable[state][bit&1])
223 if state < 0 {
224 return uint32(^state), nil
225 } else if state == 0 {
226 // Unread the bits we've read, then return errInvalidCode.
227 b.bits = (b.bits >> nBitsRead) | bitsRead
228 b.nBits += nBitsRead
229 return 0, errInvalidCode
230 }
231 }
232 }
233 234 // decodeEOL decodes the 12-bit EOL code 0000_0000_0001.
235 func decodeEOL(b *bitReader) error {
236 nBitsRead, bitsRead := uint32(0), uint64(0)
237 for {
238 bit, err := b.nextBit()
239 if err != nil {
240 if err == io.EOF {
241 err = errMissingEOL
242 }
243 return err
244 }
245 bitsRead |= bit << (63 - nBitsRead)
246 nBitsRead++
247 248 if nBitsRead < 12 {
249 if bit&1 == 0 {
250 continue
251 }
252 } else if bit&1 != 0 {
253 return nil
254 }
255 256 // Unread the bits we've read, then return errMissingEOL.
257 b.bits = (b.bits >> nBitsRead) | bitsRead
258 b.nBits += nBitsRead
259 return errMissingEOL
260 }
261 }
262 263 type reader struct {
264 br bitReader
265 subFormat SubFormat
266 267 // width is the image width in pixels.
268 width int
269 270 // rowsRemaining starts at the image height in pixels, when the reader is
271 // driven through the io.Reader interface, and decrements to zero as rows
272 // are decoded. Alternatively, it may be negative if the image height is
273 // not known in advance at the time of the NewReader call.
274 //
275 // When driven through DecodeIntoGray, this field is unused.
276 rowsRemaining int
277 278 // curr and prev hold the current and previous rows. Each element is either
279 // 0x00 (black) or 0xFF (white).
280 //
281 // prev may be nil, when processing the first row.
282 curr []byte
283 prev []byte
284 285 // ri is the read index. curr[:ri] are those bytes of curr that have been
286 // passed along via the Read method.
287 //
288 // When the reader is driven through DecodeIntoGray, instead of through the
289 // io.Reader interface, this field is unused.
290 ri int
291 292 // wi is the write index. curr[:wi] are those bytes of curr that have
293 // already been decoded via the decodeRow method.
294 //
295 // What this implementation calls wi is roughly equivalent to what the spec
296 // calls the a0 index.
297 wi int
298 299 // These fields are copied from the *Options (which may be nil).
300 align bool
301 invert bool
302 303 // atStartOfRow is whether we have just started the row. Some parts of the
304 // spec say to treat this situation as if "wi = -1".
305 atStartOfRow bool
306 307 // penColorIsWhite is whether the next run is black or white.
308 penColorIsWhite bool
309 310 // seenStartOfImage is whether we've called the startDecode method.
311 seenStartOfImage bool
312 313 // truncated is whether the input is missing the final 6 consecutive EOL's
314 // (for Group3) or 2 consecutive EOL's (for Group4). Omitting that trailer
315 // (but otherwise padding to a byte boundary, with either all 0 bits or all
316 // 1 bits) is invalid according to the spec, but happens in practice when
317 // exporting from Adobe Acrobat to TIFF + CCITT. This package silently
318 // ignores the format error for CCITT input that has been truncated in that
319 // fashion, returning the full decoded image.
320 //
321 // Detecting trailer truncation (just after the final row of pixels)
322 // requires knowing which row is the final row, and therefore does not
323 // trigger if the image height is not known in advance.
324 truncated bool
325 326 // readErr is a sticky error for the Read method.
327 readErr error
328 }
329 330 func (z *reader) Read(p []byte) (int, error) {
331 if z.readErr != nil {
332 return 0, z.readErr
333 }
334 originalP := p
335 336 for len(p) > 0 {
337 // Allocate buffers (and decode any start-of-image codes), if
338 // processing the first or second row.
339 if z.curr == nil {
340 if !z.seenStartOfImage {
341 if z.readErr = z.startDecode(); z.readErr != nil {
342 break
343 }
344 z.atStartOfRow = true
345 }
346 z.curr = make([]byte, z.width)
347 }
348 349 // Decode the next row, if necessary.
350 if z.atStartOfRow {
351 if z.rowsRemaining < 0 {
352 // We do not know the image height in advance. See if the next
353 // code is an EOL. If it is, it is consumed. If it isn't, the
354 // bitReader shouldn't advance along the bit stream, and we
355 // simply decode another row of pixel data.
356 //
357 // For the Group4 subFormat, we may need to align to a byte
358 // boundary. For the Group3 subFormat, the previous z.decodeRow
359 // call (or z.startDecode call) has already consumed one of the
360 // 6 consecutive EOL's. The next EOL is actually the second of
361 // 6, in the middle, and we shouldn't align at that point.
362 if z.align && (z.subFormat == Group4) {
363 z.br.alignToByteBoundary()
364 }
365 366 if err := z.decodeEOL(); err == errMissingEOL {
367 // No-op. It's another row of pixel data.
368 } else if err != nil {
369 z.readErr = err
370 break
371 } else {
372 if z.readErr = z.finishDecode(true); z.readErr != nil {
373 break
374 }
375 z.readErr = io.EOF
376 break
377 }
378 379 } else if z.rowsRemaining == 0 {
380 // We do know the image height in advance, and we have already
381 // decoded exactly that many rows.
382 if z.readErr = z.finishDecode(false); z.readErr != nil {
383 break
384 }
385 z.readErr = io.EOF
386 break
387 388 } else {
389 z.rowsRemaining--
390 }
391 392 if z.readErr = z.decodeRow(z.rowsRemaining == 0); z.readErr != nil {
393 break
394 }
395 }
396 397 // Pack from z.curr (1 byte per pixel) to p (1 bit per pixel).
398 packD, packS := highBits(p, z.curr[z.ri:], z.invert)
399 p = p[packD:]
400 z.ri += packS
401 402 // Prepare to decode the next row, if necessary.
403 if z.ri == len(z.curr) {
404 z.ri, z.curr, z.prev = 0, z.prev, z.curr
405 z.atStartOfRow = true
406 }
407 }
408 409 n := len(originalP) - len(p)
410 if z.invert {
411 invertBytes(originalP[:n])
412 }
413 return n, z.readErr
414 }
415 416 func (z *reader) penColor() byte {
417 if z.penColorIsWhite {
418 return 0xFF
419 }
420 return 0x00
421 }
422 423 func (z *reader) startDecode() error {
424 switch z.subFormat {
425 case Group3:
426 if err := z.decodeEOL(); err != nil {
427 return err
428 }
429 430 case Group4:
431 // No-op.
432 433 default:
434 return errUnsupportedSubFormat
435 }
436 437 z.seenStartOfImage = true
438 return nil
439 }
440 441 func (z *reader) finishDecode(alreadySeenEOL bool) error {
442 numberOfEOLs := 0
443 switch z.subFormat {
444 case Group3:
445 if z.truncated {
446 return nil
447 }
448 // The stream ends with a RTC (Return To Control) of 6 consecutive
449 // EOL's, but we should have already just seen an EOL, either in
450 // z.startDecode (for a zero-height image) or in z.decodeRow.
451 numberOfEOLs = 5
452 453 case Group4:
454 autoDetectHeight := z.rowsRemaining < 0
455 if autoDetectHeight {
456 // Aligning to a byte boundary was already handled by reader.Read.
457 } else if z.align {
458 z.br.alignToByteBoundary()
459 }
460 // The stream ends with two EOL's. If the first one is missing, and we
461 // had an explicit image height, we just assume that the trailing two
462 // EOL's were truncated and return a nil error.
463 if err := z.decodeEOL(); err != nil {
464 if (err == errMissingEOL) && !autoDetectHeight {
465 z.truncated = true
466 return nil
467 }
468 return err
469 }
470 numberOfEOLs = 1
471 472 default:
473 return errUnsupportedSubFormat
474 }
475 476 if alreadySeenEOL {
477 numberOfEOLs--
478 }
479 for ; numberOfEOLs > 0; numberOfEOLs-- {
480 if err := z.decodeEOL(); err != nil {
481 return err
482 }
483 }
484 return nil
485 }
486 487 func (z *reader) decodeEOL() error {
488 return decodeEOL(&z.br)
489 }
490 491 func (z *reader) decodeRow(finalRow bool) error {
492 z.wi = 0
493 z.atStartOfRow = true
494 z.penColorIsWhite = true
495 496 if z.align {
497 z.br.alignToByteBoundary()
498 }
499 500 switch z.subFormat {
501 case Group3:
502 for ; z.wi < len(z.curr); z.atStartOfRow = false {
503 if err := z.decodeRun(); err != nil {
504 return err
505 }
506 }
507 err := z.decodeEOL()
508 if finalRow && (err == errMissingEOL) {
509 z.truncated = true
510 return nil
511 }
512 return err
513 514 case Group4:
515 for ; z.wi < len(z.curr); z.atStartOfRow = false {
516 mode, err := decode(&z.br, modeDecodeTable[:])
517 if err != nil {
518 return err
519 }
520 rm := readerMode{}
521 if mode < uint32(len(readerModes)) {
522 rm = readerModes[mode]
523 }
524 if rm.function == nil {
525 return errInvalidMode
526 }
527 if err := rm.function(z, rm.arg); err != nil {
528 return err
529 }
530 }
531 return nil
532 }
533 534 return errUnsupportedSubFormat
535 }
536 537 func (z *reader) decodeRun() error {
538 table := blackDecodeTable[:]
539 if z.penColorIsWhite {
540 table = whiteDecodeTable[:]
541 }
542 543 total := 0
544 for {
545 n, err := decode(&z.br, table)
546 if err != nil {
547 return err
548 }
549 if n > maxWidth {
550 panic("unreachable")
551 }
552 total += int(n)
553 if total > maxWidth {
554 return errRunLengthTooLong
555 }
556 // Anything 0x3F or below is a terminal code.
557 if n <= 0x3F {
558 break
559 }
560 }
561 562 if total > (len(z.curr) - z.wi) {
563 return errRunLengthOverflowsWidth
564 }
565 dst := z.curr[z.wi : z.wi+total]
566 penColor := z.penColor()
567 for i := range dst {
568 dst[i] = penColor
569 }
570 z.wi += total
571 z.penColorIsWhite = !z.penColorIsWhite
572 573 return nil
574 }
575 576 // The various modes' semantics are based on determining a row of pixels'
577 // "changing elements": those pixels whose color differs from the one on its
578 // immediate left.
579 //
580 // The row above the first row is implicitly all white. Similarly, the column
581 // to the left of the first column is implicitly all white.
582 //
583 // For example, here's Figure 1 in "ITU-T Recommendation T.6", where the
584 // current and previous rows contain black (B) and white (w) pixels. The a?
585 // indexes point into curr, the b? indexes point into prev.
586 //
587 // b1 b2
588 // v v
589 // prev: BBBBBwwwwwBBBwwwww
590 // curr: BBBwwwwwBBBBBBwwww
591 // ^ ^ ^
592 // a0 a1 a2
593 //
594 // a0 is the "reference element" or current decoder position, roughly
595 // equivalent to what this implementation calls reader.wi.
596 //
597 // a1 is the next changing element to the right of a0, on the "coding line"
598 // (the current row).
599 //
600 // a2 is the next changing element to the right of a1, again on curr.
601 //
602 // b1 is the first changing element on the "reference line" (the previous row)
603 // to the right of a0 and of opposite color to a0.
604 //
605 // b2 is the next changing element to the right of b1, again on prev.
606 //
607 // The various modes calculate a1 (and a2, for modeH):
608 // - modePass calculates that a1 is at or to the right of b2.
609 // - modeH calculates a1 and a2 without considering b1 or b2.
610 // - modeV* calculates a1 to be b1 plus an adjustment (between -3 and +3).
611 612 const (
613 findB1 = false
614 findB2 = true
615 )
616 617 // findB finds either the b1 or b2 value.
618 func (z *reader) findB(whichB bool) int {
619 // The initial row is a special case. The previous row is implicitly all
620 // white, so that there are no changing pixel elements. We return b1 or b2
621 // to be at the end of the row.
622 if len(z.prev) != len(z.curr) {
623 return len(z.curr)
624 }
625 626 i := z.wi
627 628 if z.atStartOfRow {
629 // a0 is implicitly at -1, on a white pixel. b1 is the first black
630 // pixel in the previous row. b2 is the first white pixel after that.
631 for ; (i < len(z.prev)) && (z.prev[i] == 0xFF); i++ {
632 }
633 if whichB == findB2 {
634 for ; (i < len(z.prev)) && (z.prev[i] == 0x00); i++ {
635 }
636 }
637 return i
638 }
639 640 // As per figure 1 above, assume that the current pen color is white.
641 // First, walk past every contiguous black pixel in prev, starting at a0.
642 oppositeColor := ^z.penColor()
643 for ; (i < len(z.prev)) && (z.prev[i] == oppositeColor); i++ {
644 }
645 646 // Then walk past every contiguous white pixel.
647 penColor := ^oppositeColor
648 for ; (i < len(z.prev)) && (z.prev[i] == penColor); i++ {
649 }
650 651 // We're now at a black pixel (or at the end of the row). That's b1.
652 if whichB == findB2 {
653 // If we're looking for b2, walk past every contiguous black pixel
654 // again.
655 oppositeColor := ^penColor
656 for ; (i < len(z.prev)) && (z.prev[i] == oppositeColor); i++ {
657 }
658 }
659 660 return i
661 }
662 663 type readerMode struct {
664 function func(z *reader, arg int) error
665 arg int
666 }
667 668 var readerModes = [...]readerMode{
669 modePass: {function: readerModePass},
670 modeH: {function: readerModeH},
671 modeV0: {function: readerModeV, arg: +0},
672 modeVR1: {function: readerModeV, arg: +1},
673 modeVR2: {function: readerModeV, arg: +2},
674 modeVR3: {function: readerModeV, arg: +3},
675 modeVL1: {function: readerModeV, arg: -1},
676 modeVL2: {function: readerModeV, arg: -2},
677 modeVL3: {function: readerModeV, arg: -3},
678 modeExt: {function: readerModeExt},
679 }
680 681 func readerModePass(z *reader, arg int) error {
682 b2 := z.findB(findB2)
683 if (b2 < z.wi) || (len(z.curr) < b2) {
684 return errInvalidOffset
685 }
686 dst := z.curr[z.wi:b2]
687 penColor := z.penColor()
688 for i := range dst {
689 dst[i] = penColor
690 }
691 z.wi = b2
692 return nil
693 }
694 695 func readerModeH(z *reader, arg int) error {
696 // The first iteration finds a1. The second finds a2.
697 for i := 0; i < 2; i++ {
698 if err := z.decodeRun(); err != nil {
699 return err
700 }
701 }
702 return nil
703 }
704 705 func readerModeV(z *reader, arg int) error {
706 a1 := z.findB(findB1) + arg
707 if (a1 < z.wi) || (len(z.curr) < a1) {
708 return errInvalidOffset
709 }
710 dst := z.curr[z.wi:a1]
711 penColor := z.penColor()
712 for i := range dst {
713 dst[i] = penColor
714 }
715 z.wi = a1
716 z.penColorIsWhite = !z.penColorIsWhite
717 return nil
718 }
719 720 func readerModeExt(z *reader, arg int) error {
721 return errUnsupportedMode
722 }
723 724 // DecodeIntoGray decodes the CCITT-formatted data in r into dst.
725 //
726 // It returns an error if dst's width and height don't match the implied width
727 // and height of CCITT-formatted data.
728 func DecodeIntoGray(dst *image.Gray, r io.Reader, order Order, sf SubFormat, opts *Options) error {
729 bounds := dst.Bounds()
730 if (bounds.Dx() < 0) || (bounds.Dy() < 0) {
731 return errInvalidBounds
732 }
733 if bounds.Dx() > maxWidth {
734 return errUnsupportedWidth
735 }
736 737 z := reader{
738 br: bitReader{r: r, order: order},
739 subFormat: sf,
740 align: (opts != nil) && opts.Align,
741 invert: (opts != nil) && opts.Invert,
742 width: bounds.Dx(),
743 }
744 if err := z.startDecode(); err != nil {
745 return err
746 }
747 748 width := bounds.Dx()
749 for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
750 p := (y - bounds.Min.Y) * dst.Stride
751 z.curr = dst.Pix[p : p+width]
752 if err := z.decodeRow(y+1 == bounds.Max.Y); err != nil {
753 return err
754 }
755 z.curr, z.prev = nil, z.curr
756 }
757 758 if err := z.finishDecode(false); err != nil {
759 return err
760 }
761 762 if z.invert {
763 for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
764 p := (y - bounds.Min.Y) * dst.Stride
765 invertBytes(dst.Pix[p : p+width])
766 }
767 }
768 769 return nil
770 }
771 772 // NewReader returns an io.Reader that decodes the CCITT-formatted data in r.
773 // The resultant byte stream is one bit per pixel (MSB first), with 1 meaning
774 // white and 0 meaning black. Each row in the result is byte-aligned.
775 //
776 // A negative height, such as passing AutoDetectHeight, means that the image
777 // height is not known in advance. A negative width is invalid.
778 func NewReader(r io.Reader, order Order, sf SubFormat, width int, height int, opts *Options) io.Reader {
779 readErr := error(nil)
780 if width < 0 {
781 readErr = errInvalidBounds
782 } else if width > maxWidth {
783 readErr = errUnsupportedWidth
784 }
785 786 return &reader{
787 br: bitReader{r: r, order: order},
788 subFormat: sf,
789 align: (opts != nil) && opts.Align,
790 invert: (opts != nil) && opts.Invert,
791 width: width,
792 rowsRemaining: height,
793 readErr: readErr,
794 }
795 }
796