@@ -9,7 +9,7 @@ interface ChannelInfo {
99 length : number ;
1010}
1111
12- export const supportedColorModes = [ ColorMode . Bitmap , ColorMode . Grayscale , ColorMode . RGB , ColorMode . Indexed ] ;
12+ export const supportedColorModes = [ ColorMode . Bitmap , ColorMode . Grayscale , ColorMode . RGB , ColorMode . Indexed , ColorMode . CMYK ] ;
1313const colorModes = [ 'bitmap' , 'grayscale' , 'indexed' , 'RGB' , 'CMYK' , 'multichannel' , 'duotone' , 'lab' ] ;
1414
1515function setupGrayscale ( data : PixelData ) {
@@ -635,7 +635,7 @@ function readLayerChannelImageData(reader: PsdReader, psd: Psd, layer: Layer, ch
635635 if ( cmyk ) {
636636 const cmykData = imageData ;
637637 imageData = createImageData ( cmykData . width , cmykData . height ) ;
638- cmykToRgb ( cmykData , imageData , false ) ;
638+ cmykToRgb ( cmykData , imageData ) ;
639639 }
640640
641641 if ( reader . useImageData ) {
@@ -802,10 +802,14 @@ function readImageData(reader: PsdReader, psd: Psd) {
802802 break ;
803803 }
804804 case ColorMode . CMYK : {
805- if ( bitsPerChannel !== 8 ) throw new Error ( 'bitsPerChannel Not supproted' ) ;
806- if ( psd . channels !== 4 ) throw new Error ( `Invalid channel count` ) ;
805+ if ( bitsPerChannel !== 8 ) throw new Error ( 'bitsPerChannel Not supported' ) ;
806+ // there is additional color channel for cmyk when channels === 5
807+ if ( psd . channels !== 4 && psd . channels !== 5 ) throw new Error ( `Invalid channel count` ) ;
808+ // there is additional alpha channel for cmyk
809+ const channelLen = psd . channels ! + 1 ;
807810
808811 const channels = [ 0 , 1 , 2 , 3 ] ;
812+ const haveAlpha = reader . globalAlpha || psd . channels === 5 ;
809813 if ( reader . globalAlpha ) channels . push ( 4 ) ;
810814
811815 if ( compression === Compression . RawData ) {
@@ -818,12 +822,12 @@ function readImageData(reader: PsdReader, psd: Psd) {
818822 const cmykImageData : PixelData = {
819823 width : imageData . width ,
820824 height : imageData . height ,
821- data : new Uint8Array ( imageData . width * imageData . height * 5 ) ,
825+ data : new Uint8Array ( imageData . width * imageData . height * channelLen ) ,
822826 } ;
823827
824828 const start = reader . offset ;
825- readDataRLE ( reader , cmykImageData , psd . width , psd . height , bitsPerChannel , 5 , channels , reader . large ) ;
826- cmykToRgb ( cmykImageData , imageData , true ) ;
829+ readDataRLE ( reader , cmykImageData , psd . width , psd . height , bitsPerChannel , channelLen , channels , reader . large ) ;
830+ cmykToRgb ( cmykImageData , imageData , ! haveAlpha , channelLen ) ;
827831
828832 if ( RAW_IMAGE_DATA ) ( psd as any ) . imageDataRaw = new Uint8Array ( reader . view . buffer , reader . view . byteOffset + start , reader . offset - start ) ;
829833 } else {
@@ -860,12 +864,12 @@ function readImageData(reader: PsdReader, psd: Psd) {
860864 }
861865}
862866
863- function cmykToRgb ( cmyk : PixelData , rgb : PixelData , reverseAlpha : boolean ) {
867+ function cmykToRgb ( cmyk : PixelData , rgb : PixelData , reverseAlpha = false , channelLen = 5 ) {
864868 const size = rgb . width * rgb . height * 4 ;
865869 const srcData = cmyk . data ;
866870 const dstData = rgb . data ;
867871
868- for ( let src = 0 , dst = 0 ; dst < size ; src += 5 , dst += 4 ) {
872+ for ( let src = 0 , dst = 0 ; dst < size ; src += channelLen , dst += 4 ) {
869873 const c = srcData [ src ] ;
870874 const m = srcData [ src + 1 ] ;
871875 const y = srcData [ src + 2 ] ;
@@ -1033,7 +1037,8 @@ export function readDataRLE(reader: PsdReader, pixelData: PixelData | undefined,
10331037
10341038 if ( bitDepth !== 1 && bitDepth !== 8 ) throw new Error ( `Invalid bit depth (${ bitDepth } )` ) ;
10351039
1036- const extraLimit = ( step - 1 ) | 0 ; // 3 for rgb, 4 for cmyk
1040+ const extraLimit = ( step - 1 ) | 0 ; // 3 for rgb, 4 for cmyk, 5 for cmyk+extraColor
1041+
10371042
10381043 for ( let c = 0 , li = 0 ; c < offsets . length ; c ++ ) {
10391044 const offset = offsets [ c ] | 0 ;
0 commit comments