Skip to content

Commit 96659b7

Browse files
committed
Fix #789
1 parent dae09eb commit 96659b7

File tree

2 files changed

+55
-24
lines changed

2 files changed

+55
-24
lines changed

pkg/pdfcpu/extract.go

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -314,14 +314,7 @@ func prepareExtractImage(sd *types.StreamDict) (string, string, types.Dict, bool
314314

315315
return filters, lastFilter, d, imgMask
316316
}
317-
318-
func img(
319-
ctx *model.Context,
320-
sd *types.StreamDict,
321-
thumb, imgMask bool,
322-
resourceID, filters, lastFilter string,
323-
objNr int) (*model.Image, error) {
324-
317+
func decodeImage(ctx *model.Context, sd *types.StreamDict, filters, lastFilter string, objNr int) error {
325318
// CCITTDecoded images / (bit) masks don't have a ColorSpace attribute, but we render image files.
326319
if lastFilter == filter.CCITTFax {
327320
if _, err := ctx.DereferenceDictEntry(sd.Dict, "ColorSpace"); err != nil {
@@ -332,7 +325,7 @@ func img(
332325
if lastFilter == filter.DCT {
333326
comp, err := ColorSpaceComponents(ctx.XRefTable, sd)
334327
if err != nil {
335-
return nil, err
328+
return err
336329
}
337330
sd.CSComponents = comp
338331
}
@@ -341,7 +334,7 @@ func img(
341334

342335
case filter.DCT, filter.JPX, filter.Flate, filter.CCITTFax, filter.RunLength:
343336
if err := sd.Decode(); err != nil {
344-
return nil, err
337+
return err
345338
}
346339

347340
default:
@@ -352,7 +345,25 @@ func img(
352345
if log.CLIEnabled() {
353346
log.CLI.Println(msg)
354347
}
355-
return nil, nil
348+
return nil
349+
}
350+
351+
return nil
352+
}
353+
354+
func img(
355+
ctx *model.Context,
356+
sd *types.StreamDict,
357+
thumb, imgMask bool,
358+
resourceID, filters, lastFilter string,
359+
objNr int) (*model.Image, error) {
360+
361+
if sd.FilterPipeline == nil {
362+
sd.Content = sd.Raw
363+
} else {
364+
if err := decodeImage(ctx, sd, filters, lastFilter, objNr); err != nil {
365+
return nil, err
366+
}
356367
}
357368

358369
r, t, err := RenderImage(ctx.XRefTable, sd, thumb, resourceID, objNr)
@@ -383,10 +394,6 @@ func ExtractImage(ctx *model.Context, sd *types.StreamDict, thumb bool, resource
383394
return imageStub(ctx, sd, resourceID, filters, lastFilter, decodeParms, thumb, imgMask, objNr)
384395
}
385396

386-
if sd.FilterPipeline == nil {
387-
return nil, nil
388-
}
389-
390397
return img(ctx, sd, thumb, imgMask, resourceID, filters, lastFilter, objNr)
391398
}
392399

pkg/pdfcpu/writeImage.go

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ func imageForCMYKWithoutSoftMask(im *PDFImage) image.Image {
259259
for y := 0; y < im.h; y++ {
260260
for x := 0; x < im.w; x++ {
261261
img.Set(x, y, color.CMYK{C: b[i], M: b[i+1], Y: b[i+2], K: b[i+3]})
262-
i += 4
262+
i += im.comp
263263
}
264264
}
265265

@@ -773,25 +773,45 @@ func renderIndexed(xRefTable *model.XRefTable, im *PDFImage, resourceName string
773773
}
774774

775775
func renderDeviceN(xRefTable *model.XRefTable, im *PDFImage, resourceName string, cs types.Array) (io.Reader, string, error) {
776+
if im.comp <= 4 {
777+
switch im.comp {
778+
case 1:
779+
// Gray
780+
return renderDeviceGrayToPNG(im, resourceName)
776781

777-
switch im.comp {
778-
case 1:
782+
case 3:
783+
// RGB
784+
return renderDeviceRGBToPNG(im, resourceName)
785+
786+
case 4:
787+
// CMYK
788+
return renderDeviceCMYKToTIFF(im, resourceName)
789+
}
790+
}
791+
792+
alternateCS, ok := cs[2].(types.Name)
793+
if !ok {
794+
return nil, "", nil
795+
}
796+
797+
switch alternateCS {
798+
case model.DeviceGrayCS:
779799
// Gray
780800
return renderDeviceGrayToPNG(im, resourceName)
781801

782-
case 3:
802+
case model.DeviceRGBCS:
783803
// RGB
784804
return renderDeviceRGBToPNG(im, resourceName)
785805

786-
case 4:
806+
case model.DeviceCMYKCS:
787807
// CMYK
788808
return renderDeviceCMYKToTIFF(im, resourceName)
789809
}
790810

791811
return nil, "", nil
792812
}
793813

794-
func renderFlateEncodedImage(xRefTable *model.XRefTable, sd *types.StreamDict, thumb bool, resourceName string, objNr int) (io.Reader, string, error) {
814+
func renderImage(xRefTable *model.XRefTable, sd *types.StreamDict, thumb bool, resourceName string, objNr int) (io.Reader, string, error) {
795815
// If color space is CMYK then write .tif else write .png
796816

797817
pdfImage, err := pdfImage(xRefTable, sd, thumb, objNr)
@@ -820,7 +840,7 @@ func renderFlateEncodedImage(xRefTable *model.XRefTable, sd *types.StreamDict, t
820840

821841
default:
822842
if log.InfoEnabled() {
823-
log.Info.Printf("renderFlateEncodedImage: objNr=%d, unsupported name colorspace %s\n", objNr, cs.String())
843+
log.Info.Printf("renderImage: objNr=%d, unsupported name colorspace %s\n", objNr, cs.String())
824844
}
825845
}
826846

@@ -846,7 +866,7 @@ func renderFlateEncodedImage(xRefTable *model.XRefTable, sd *types.StreamDict, t
846866

847867
default:
848868
if log.InfoEnabled() {
849-
log.Info.Printf("renderFlateEncodedImage: objNr=%d, unsupported array colorspace %s\n", objNr, csn)
869+
log.Info.Printf("renderImage: objNr=%d, unsupported array colorspace %s\n", objNr, csn)
850870
}
851871
}
852872

@@ -908,12 +928,16 @@ func renderDCTToPNG(xRefTable *model.XRefTable, sd *types.StreamDict, thumb bool
908928
func RenderImage(xRefTable *model.XRefTable, sd *types.StreamDict, thumb bool, resourceName string, objNr int) (io.Reader, string, error) {
909929
// Image compression is the last filter in the pipeline.
910930

931+
if len(sd.FilterPipeline) == 0 {
932+
return renderImage(xRefTable, sd, thumb, resourceName, objNr)
933+
}
934+
911935
f := sd.FilterPipeline[len(sd.FilterPipeline)-1].Name
912936

913937
switch f {
914938

915939
case filter.Flate, filter.CCITTFax, filter.RunLength:
916-
return renderFlateEncodedImage(xRefTable, sd, thumb, resourceName, objNr)
940+
return renderImage(xRefTable, sd, thumb, resourceName, objNr)
917941

918942
case filter.DCT:
919943
if sd.CSComponents == 4 {

0 commit comments

Comments
 (0)