Commit 977a27848 for imagemagick.org
commit 977a27848b533c98d7819afd51a5032449607cc1
Author: Cristy <urban-warrior@imagemagick.org>
Date: Tue Sep 1 19:37:53 2026 -0400
for now, limit c2pa support to decoding only
diff --git a/coders/c2pa.c b/coders/c2pa.c
index 530c12f47..a31e05b6c 100644
--- a/coders/c2pa.c
+++ b/coders/c2pa.c
@@ -197,7 +197,6 @@ ModuleExport size_t RegisterC2PAImage(void)
entry->decoder=(DecodeImageHandler *) ReadC2PAImage;
entry->encoder=(EncodeImageHandler *) WriteC2PAImage;
entry->flags|=CoderDecoderSeekableStreamFlag;
- entry->flags|=CoderEncoderSeekableStreamFlag;
entry->flags^=CoderBlobSupportFlag;
entry->format_type=ExplicitFormatType;
(void) RegisterMagickInfo(entry);
@@ -227,219 +226,3 @@ ModuleExport void UnregisterC2PAImage(void)
{
(void) UnregisterMagickInfo("C2PA");
}
-
-/*
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% %
-% %
-% %
-% W r i t e C 2 P A I m a g e %
-% %
-% %
-% %
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% WriteC2PAImage() writes an image and signs it with C2PA content
-% credentials. The image is first written to a temporary file in a format
-% the C2PA delegate understands (see the c2pa:format define, PNG by default)
-% and is then handed to the c2pa:encode delegate for signing. The signed
-% bytes the delegate returns in %o are copied verbatim to the destination so
-% the manifest and its signature remain intact.
-%
-% The format of the WriteC2PAImage method is:
-%
-% MagickBooleanType WriteC2PAImage(const ImageInfo *image_info,
-% Image *image,ExceptionInfo *exception)
-%
-% A description of each parameter follows.
-%
-% o image_info: the image info.
-%
-% o image: The image.
-%
-% o exception: return any errors or warnings in this structure.
-%
-*/
-static MagickBooleanType WriteC2PAImage(const ImageInfo *image_info,
- Image *image,ExceptionInfo *exception)
-{
- static const char
- *credentials[] = { "c2pa:key", "c2pa:password", "c2pa:cert",
- "c2pa:manifest", (const char *) NULL };
-
- char
- *buffer,
- format[MagickPathExtent],
- unique[MagickPathExtent];
-
- const char
- *option;
-
- FILE
- *file;
-
- Image
- *write_image;
-
- ImageInfo
- *write_info;
-
- MagickBooleanType
- status;
-
- size_t
- length,
- quantum;
-
- ssize_t
- count,
- i;
-
- assert(image_info != (const ImageInfo *) NULL);
- assert(image_info->signature == MagickCoreSignature);
- assert(image != (Image *) NULL);
- assert(image->signature == MagickCoreSignature);
- assert(exception != (ExceptionInfo *) NULL);
- assert(exception->signature == MagickCoreSignature);
- if (IsEventLogging() != MagickFalse)
- (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
- /*
- A manifest is required to sign an image.
- */
- option=GetImageOption(image_info,"c2pa:manifest");
- if (option == (const char *) NULL)
- option=GetImageArtifact(image,"c2pa:manifest");
- if (option == (const char *) NULL)
- {
- (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
- "MustSpecifyImageManifest","`%s'",image->filename);
- return(MagickFalse);
- }
- /*
- Determine the intermediate image format the delegate signs.
- */
- option=GetImageOption(image_info,"c2pa:format");
- if (option == (const char *) NULL)
- option=GetImageArtifact(image,"c2pa:format");
- if (option != (const char *) NULL)
- (void) CopyMagickString(format,option,MagickPathExtent);
- else
- if ((*image->magick != '\0') &&
- (LocaleCompare(image->magick,"C2PA") != 0))
- (void) CopyMagickString(format,image->magick,MagickPathExtent);
- else
- (void) CopyMagickString(format,"PNG",MagickPathExtent);
- /*
- Write the image to a unique file the delegate signs (%i).
- */
- if (AcquireUniqueFilename(unique) == MagickFalse)
- {
- ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
- image->filename);
- return(MagickFalse);
- }
- write_image=CloneImage(image,0,0,MagickTrue,exception);
- if (write_image == (Image *) NULL)
- {
- (void) RelinquishUniqueFileResource(unique);
- return(MagickFalse);
- }
- write_info=CloneImageInfo(image_info);
- SetImageInfoBlob(write_info,(void *) NULL,0);
- write_info->temporary=MagickFalse;
- write_info->adjoin=MagickTrue;
- (void) CopyMagickString(write_info->magick,format,MagickPathExtent);
- (void) FormatLocaleString(write_info->filename,MagickPathExtent,"%s:%s",
- format,unique);
- (void) CopyMagickString(write_image->filename,write_info->filename,
- MagickPathExtent);
- status=WriteImage(write_info,write_image,exception);
- if (status == MagickFalse)
- {
- write_info=DestroyImageInfo(write_info);
- write_image=DestroyImage(write_image);
- (void) RelinquishUniqueFileResource(unique);
- return(MagickFalse);
- }
- /*
- Promote the signing credentials to artifacts so %[c2pa:*] resolves when
- the delegate command is interpreted.
- */
- for (i=0; credentials[i] != (const char *) NULL; i++)
- {
- option=GetImageOption(image_info,credentials[i]);
- if (option != (const char *) NULL)
- (void) SetImageArtifact(write_image,credentials[i],option);
- }
- /*
- Sign the image with the c2pa:encode delegate.
- */
- (void) CopyMagickString(write_info->filename,unique,MagickPathExtent);
- (void) CopyMagickString(write_image->filename,unique,MagickPathExtent);
- (void) CopyMagickString(write_image->magick,format,MagickPathExtent);
- status=InvokeDelegate(write_info,write_image,(char *) NULL,"c2pa:encode",
- exception);
- write_image=DestroyImage(write_image);
- (void) RelinquishUniqueFileResource(unique);
- if (status == MagickFalse)
- {
- if (*write_info->unique != '\0')
- (void) RelinquishUniqueFileResource(write_info->unique);
- write_info=DestroyImageInfo(write_info);
- return(MagickFalse);
- }
- /*
- Copy the signed image the delegate returned in %o; the bytes are written
- verbatim so the manifest and its signature are preserved.
- */
- file=fopen_utf8(write_info->unique,"rb");
- if (file == (FILE *) NULL)
- {
- ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
- write_info->unique);
- (void) RelinquishUniqueFileResource(write_info->unique);
- write_info=DestroyImageInfo(write_info);
- return(MagickFalse);
- }
- status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
- if (status == MagickFalse)
- {
- (void) fclose(file);
- (void) RelinquishUniqueFileResource(write_info->unique);
- write_info=DestroyImageInfo(write_info);
- return(MagickFalse);
- }
- quantum=(size_t) MagickMaxBufferExtent;
- buffer=(char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
- if (buffer == (char *) NULL)
- {
- (void) fclose(file);
- (void) CloseBlob(image);
- (void) RelinquishUniqueFileResource(write_info->unique);
- write_info=DestroyImageInfo(write_info);
- ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
- image->filename);
- }
- for (length=fread(buffer,1,quantum,file); length != 0; )
- {
- count=0;
- for (i=0; i < (ssize_t) length; i+=count)
- {
- count=WriteBlob(image,length-(size_t) i,(unsigned char *) buffer+i);
- if (count <= 0)
- break;
- }
- if (i < (ssize_t) length)
- break;
- length=fread(buffer,1,quantum,file);
- }
- if (ferror(file) != 0)
- status=MagickFalse;
- (void) fclose(file);
- buffer=(char *) RelinquishMagickMemory(buffer);
- if (CloseBlob(image) == MagickFalse)
- status=MagickFalse;
- (void) RelinquishUniqueFileResource(write_info->unique);
- write_info=DestroyImageInfo(write_info);
- return(status);
-}
diff --git a/config/delegates.xml.in b/config/delegates.xml.in
index 89aeb15b7..a8494eb2b 100644
--- a/config/delegates.xml.in
+++ b/config/delegates.xml.in
@@ -63,7 +63,6 @@
<delegate decode="png" encode="bpg" command="@SHELL_QUOTE@@BPGEncodeDelegate@@SHELL_QUOTE@ -b 12 -q @SHELL_QUOTE@%~@SHELL_QUOTE@ -o @SHELL_QUOTE@%o@SHELL_QUOTE@ @SHELL_QUOTE@%i@SHELL_QUOTE@"/>
<delegate decode="blender" command="@SHELL_QUOTE@@BlenderDecodeDelegate@@SHELL_QUOTE@ -b @SHELL_QUOTE@%i@SHELL_QUOTE@ -F PNG -o @SHELL_QUOTE@%o@SHELL_QUOTE@@SHELL_QUOTE@\n@SHELL_QUOTE@@ConvertDelegate@@SHELL_QUOTE@ -concatenate @SHELL_QUOTE@%o*.png@SHELL_QUOTE@ @SHELL_QUOTE@%o@SHELL_QUOTE@"/>
<delegate decode="c2pa:decode" command="@SHELL_QUOTE@@C2PADecodeDelegate@@SHELL_QUOTE@ --crjson @SHELL_QUOTE@%i@SHELL_QUOTE@ > @SHELL_QUOTE@%u.json@SHELL_QUOTE@;"/>
- <delegate encode="c2pa:encode" command="@SHELL_QUOTE@@C2PAEncodeDelegate@@SHELL_QUOTE@ @SHELL_QUOTE@%i@SHELL_QUOTE@ --manifest @SHELL_QUOTE@%[c2pa:manifest]@SHELL_QUOTE@ -config @SHELL_QUOTE@%s@SHELL_QUOTE@ --force --output @SHELL_QUOTE@%o@SHELL_QUOTE@"/>
<delegate decode="browse" stealth="True" spawn="True" command="@SHELL_QUOTE@@BrowseDelegate@@SHELL_QUOTE@ https://imagemagick.org/; @RMDelegate@ @SHELL_QUOTE@%i@SHELL_QUOTE@"/>
<delegate decode="http:decode" command="@SHELL_QUOTE@@WWWDecodeDelegate@@SHELL_QUOTE@ -s -L -o @SHELL_QUOTE@%u.dat@SHELL_QUOTE@ @SHELL_QUOTE@http:%M@SHELL_QUOTE@"/>
<delegate decode="https:decode" command="@SHELL_QUOTE@@WWWDecodeDelegate@@SHELL_QUOTE@ -s -L -o @SHELL_QUOTE@%u.dat@SHELL_QUOTE@ @SHELL_QUOTE@https:%M@SHELL_QUOTE@"/>