54#include "MagickCore/studio.h"
55#include "MagickCore/cache.h"
56#include "MagickCore/cache-private.h"
57#include "MagickCore/distribute-cache.h"
58#include "MagickCore/distribute-cache-private.h"
59#include "MagickCore/exception.h"
60#include "MagickCore/exception-private.h"
61#include "MagickCore/geometry.h"
62#include "MagickCore/image.h"
63#include "MagickCore/image-private.h"
64#include "MagickCore/list.h"
65#include "MagickCore/locale_.h"
66#include "MagickCore/memory_.h"
67#include "MagickCore/nt-base-private.h"
68#include "MagickCore/pixel.h"
69#include "MagickCore/policy.h"
70#include "MagickCore/random_.h"
71#include "MagickCore/registry.h"
72#include "MagickCore/splay-tree.h"
73#include "MagickCore/string_.h"
74#include "MagickCore/string-private.h"
75#include "MagickCore/utility-private.h"
76#include "MagickCore/version.h"
77#include "MagickCore/version-private.h"
78#undef MAGICKCORE_HAVE_DISTRIBUTE_CACHE
79#if defined(MAGICKCORE_DPC_SUPPORT)
80#if defined(MAGICKCORE_HAVE_SOCKET) && defined(MAGICKCORE_THREAD_SUPPORT)
81#include <netinet/in.h>
83#include <sys/socket.h>
85#define CLOSE_SOCKET(socket) (void) close_utf8(socket)
86#define HANDLER_RETURN_TYPE void *
87#define HANDLER_RETURN_VALUE (void *) NULL
88#define SOCKET_TYPE int
89#define LENGTH_TYPE size_t
90#define MAGICKCORE_HAVE_DISTRIBUTE_CACHE 1
91#elif defined(_MSC_VER)
92#define CLOSE_SOCKET(socket) (void) closesocket(socket)
93#define HANDLER_RETURN_TYPE DWORD WINAPI
94#define HANDLER_RETURN_VALUE 0
95#define SOCKET_TYPE SOCKET
96#define LENGTH_TYPE int
97#define MAGICKCORE_HAVE_DISTRIBUTE_CACHE 1
98#define MAGICKCORE_HAVE_WINSOCK2 1
105#define DPCHostname "127.0.0.1"
106#define DPCPendingConnections 10
108#define DPCSessionKeyLength 8
110# define MSG_NOSIGNAL 0
116#ifdef MAGICKCORE_HAVE_WINSOCK2
121 *wsaData = (WSADATA*) NULL;
147#if !defined(MAGICKCORE_HAVE_DISTRIBUTE_CACHE)
148static inline MagickOffsetType dpc_read(
int magick_unused(file),
149 const MagickSizeType magick_unused(length),
150 unsigned char *magick_restrict magick_unused(message))
152 magick_unreferenced(file);
153 magick_unreferenced(length);
154 magick_unreferenced(message);
158static inline MagickOffsetType dpc_read(
int file,
const MagickSizeType length,
159 unsigned char *magick_restrict message)
168 for (i=0; i < (MagickOffsetType) length; i+=count)
170 count=recv(file,(
char *) message+i,(LENGTH_TYPE) MagickMin(length-
171 (MagickSizeType) i,(MagickSizeType) MagickMaxBufferExtent),0);
183#if defined(MAGICKCORE_HAVE_WINSOCK2)
184static void InitializeWinsock2(MagickBooleanType use_lock)
186 if (use_lock != MagickFalse)
189 ActivateSemaphoreInfo(&winsock2_semaphore);
190 LockSemaphoreInfo(winsock2_semaphore);
192 if (wsaData == (WSADATA *) NULL)
194 wsaData=(WSADATA *) AcquireMagickMemory(
sizeof(WSADATA));
195 if (WSAStartup(MAKEWORD(2,2),wsaData) != 0)
196 ThrowFatalException(CacheFatalError,
"WSAStartup failed");
198 if (use_lock != MagickFalse)
199 UnlockSemaphoreInfo(winsock2_semaphore);
203#if !defined(MAGICKCORE_HAVE_DISTRIBUTE_CACHE)
204static int ConnectPixelCacheServer(
const char *magick_unused(hostname),
205 const int magick_unused(port),
size_t *magick_unused(session_key),
208 magick_unreferenced(hostname);
209 magick_unreferenced(port);
210 magick_unreferenced(session_key);
211 (void) ThrowMagickException(exception,GetMagickModule(),MissingDelegateError,
212 "DelegateLibrarySupportNotBuiltIn",
"distributed pixel cache");
216static int ConnectPixelCacheServer(
const char *hostname,
const int port,
220 service[MagickPathExtent],
243#if defined(MAGICKCORE_HAVE_WINSOCK2)
244 InitializeWinsock2(MagickTrue);
246 (void) memset(&hint,0,
sizeof(hint));
247 hint.ai_family=AF_INET;
248 hint.ai_socktype=SOCK_STREAM;
249 hint.ai_flags=AI_PASSIVE;
250 (void) FormatLocaleString(service,MagickPathExtent,
"%d",port);
251 status=getaddrinfo(hostname,service,&hint,&result);
254 (void) ThrowMagickException(exception,GetMagickModule(),CacheError,
255 "DistributedPixelCache",
"'%s': %s",hostname,GetExceptionMessage(errno));
258 client_socket=socket(result->ai_family,result->ai_socktype,
259 result->ai_protocol);
260 if (client_socket == -1)
262 freeaddrinfo(result);
263 (void) ThrowMagickException(exception,GetMagickModule(),CacheError,
264 "DistributedPixelCache",
"'%s': %s",hostname,GetExceptionMessage(errno));
267 status=connect(client_socket,result->ai_addr,(socklen_t) result->ai_addrlen);
268 freeaddrinfo(result);
271 CLOSE_SOCKET(client_socket);
272 (void) ThrowMagickException(exception,GetMagickModule(),CacheError,
273 "DistributedPixelCache",
"'%s': %s",hostname,GetExceptionMessage(errno));
276 count=recv(client_socket,(
char *) session_key,
sizeof(*session_key),0);
279 CLOSE_SOCKET(client_socket);
280 (void) ThrowMagickException(exception,GetMagickModule(),CacheError,
281 "DistributedPixelCache",
"'%s': %s",hostname,GetExceptionMessage(errno));
287 shared_secret=GetPolicyValue(
"cache:shared-secret");
288 if (shared_secret == (
char *) NULL)
290 CLOSE_SOCKET(client_socket);
291 (void) ThrowMagickException(exception,GetMagickModule(),CacheError,
292 "DistributedPixelCache",
"'%s': shared secret required",hostname);
295 nonce=StringToStringInfo(shared_secret);
296 if (GetMagickSignature(nonce) != *session_key)
298 CLOSE_SOCKET(client_socket);
299 (void) ThrowMagickException(exception,GetMagickModule(),CacheError,
300 "DistributedPixelCache",
"'%s' authentication failed",hostname);
303 shared_secret=DestroyString(shared_secret);
304 nonce=DestroyStringInfo(nonce);
305 return(client_socket);
328 hosts=(
char *) GetImageRegistry(StringRegistryType,
"cache:hosts",exception);
329 if (hosts == (
char *) NULL)
332 return(AcquireString(DPCHostname));
334 (void) SubstituteString(&hosts,
",",
" ");
335 hostlist=StringToArgv(hosts,&argc);
336 hosts=DestroyString(hosts);
337 if (hostlist == (
char **) NULL)
340 return(AcquireString(DPCHostname));
342 hosts=AcquireString(hostlist[(
id++ % ((
size_t) argc-1))+1]);
343 for (i=0; i < (ssize_t) argc; i++)
344 hostlist[i]=DestroyString(hostlist[i]);
345 hostlist=(
char **) RelinquishMagickMemory(hostlist);
346 (void) SubstituteString(&hosts,
":",
" ");
347 hostlist=StringToArgv(hosts,&argc);
348 if (hostlist == (
char **) NULL)
351 return(AcquireString(DPCHostname));
353 host=AcquireString(hostlist[1]);
354 if (hostlist[2] == (
char *) NULL)
357 *port=StringToLong(hostlist[2]);
358 for (i=0; i < (ssize_t) argc; i++)
359 hostlist[i]=DestroyString(hostlist[i]);
360 hostlist=(
char **) RelinquishMagickMemory(hostlist);
380 sizeof(*server_info));
381 (void) memset(server_info,0,
sizeof(*server_info));
382 server_info->signature=MagickCoreSignature;
384 hostname=GetHostname(&server_info->port,exception);
386 server_info->file=ConnectPixelCacheServer(hostname,server_info->port,
387 &session_key,exception);
388 if (server_info->file == -1)
389 server_info=DestroyDistributeCacheInfo(server_info);
392 server_info->session_key=session_key;
393 (void) CopyMagickString(server_info->hostname,hostname,MagickPathExtent);
394 server_info->debug=(GetLogEventMask() & CacheEvent) != 0 ? MagickTrue :
397 hostname=DestroyString(hostname);
429 assert(server_info->signature == MagickCoreSignature);
430#if defined(MAGICKCORE_HAVE_DISTRIBUTE_CACHE)
431 if (server_info->file > 0)
432 CLOSE_SOCKET(server_info->file);
434 server_info->signature=(~MagickCoreSignature);
465#if !defined(MAGICKCORE_HAVE_DISTRIBUTE_CACHE)
466static inline MagickOffsetType dpc_send(
int magick_unused(file),
467 const MagickSizeType magick_unused(length),
468 const void *magick_restrict magick_unused(message))
470 magick_unreferenced(file);
471 magick_unreferenced(length);
472 magick_unreferenced(message);
476static inline MagickOffsetType dpc_send(
int file,
const MagickSizeType length,
477 const void *magick_restrict message)
489 for (i=0; i < (MagickOffsetType) length; i+=count)
491 count=(MagickOffsetType) send(file,(
char *) message+i,(LENGTH_TYPE)
492 MagickMin(length-(MagickSizeType) i,(MagickSizeType) MagickMaxBufferExtent),
505#if !defined(MAGICKCORE_HAVE_DISTRIBUTE_CACHE)
506MagickExport
void DistributePixelCacheServer(
const int magick_unused(port),
509 magick_unreferenced(port);
510 magick_unreferenced(exception);
511 ThrowFatalException(MissingDelegateError,
"DelegateLibrarySupportNotBuiltIn");
514static MagickBooleanType DestroyDistributeCache(
SplayTreeInfo *registry,
515 const size_t session_key)
518 key = (MagickAddressType) session_key;
523 return(DeleteNodeFromSplayTree(registry,(
const void *) key));
526static MagickBooleanType OpenDistributeCache(
SplayTreeInfo *registry,
int file,
533 key = (MagickAddressType) session_key;
545 message[MagickPathExtent],
551 image=AcquireImage((
ImageInfo *) NULL,exception);
552 if (image == (
Image *) NULL)
554 length=
sizeof(image->storage_class)+
sizeof(image->colorspace)+
555 sizeof(image->alpha_trait)+
sizeof(image->channels)+
sizeof(image->columns)+
556 sizeof(image->rows)+
sizeof(image->number_channels)+MaxPixelChannels*
557 sizeof(*image->channel_map)+
sizeof(image->metacontent_extent);
558 count=dpc_read(file,length,message);
559 if (count != (MagickOffsetType) length)
565 (void) memcpy(&image->storage_class,p,
sizeof(image->storage_class));
566 p+=(ptrdiff_t)
sizeof(image->storage_class);
567 (void) memcpy(&image->colorspace,p,
sizeof(image->colorspace));
568 p+=(ptrdiff_t)
sizeof(image->colorspace);
569 (void) memcpy(&image->alpha_trait,p,
sizeof(image->alpha_trait));
570 p+=(ptrdiff_t)
sizeof(image->alpha_trait);
571 (void) memcpy(&image->channels,p,
sizeof(image->channels));
572 p+=(ptrdiff_t)
sizeof(image->channels);
573 (void) memcpy(&image->columns,p,
sizeof(image->columns));
574 p+=(ptrdiff_t)
sizeof(image->columns);
575 (void) memcpy(&image->rows,p,
sizeof(image->rows));
576 p+=(ptrdiff_t)
sizeof(image->rows);
577 (void) memcpy(&image->number_channels,p,
sizeof(image->number_channels));
578 p+=(ptrdiff_t)
sizeof(image->number_channels);
579 (void) memcpy(image->channel_map,p,MaxPixelChannels*
580 sizeof(*image->channel_map));
581 p+=(ptrdiff_t) MaxPixelChannels*
sizeof(*image->channel_map);
582 (void) memcpy(&image->metacontent_extent,p,
sizeof(image->metacontent_extent));
583 p+=(ptrdiff_t)
sizeof(image->metacontent_extent);
584 if (SyncImagePixelCache(image,exception) == MagickFalse)
586 status=AddValueToSplayTree(registry,(
const void *) key,image);
590static MagickBooleanType ReadDistributeCacheMetacontent(
SplayTreeInfo *registry,
603 key = (MagickAddressType) session_key;
615 message[MagickPathExtent],
621 image=(
Image *) GetValueFromSplayTree(registry,(
const void *) key);
622 if (image == (
Image *) NULL)
624 length=
sizeof(region.width)+
sizeof(region.height)+
sizeof(region.x)+
625 sizeof(region.y)+
sizeof(length);
626 count=dpc_read(file,length,message);
627 if (count != (MagickOffsetType) length)
630 (void) memcpy(®ion.width,q,
sizeof(region.width));
631 q+=(ptrdiff_t)
sizeof(region.width);
632 (void) memcpy(®ion.height,q,
sizeof(region.height));
633 q+=(ptrdiff_t)
sizeof(region.height);
634 (void) memcpy(®ion.x,q,
sizeof(region.x));
635 q+=(ptrdiff_t)
sizeof(region.x);
636 (void) memcpy(®ion.y,q,
sizeof(region.y));
637 q+=(ptrdiff_t)
sizeof(region.y);
638 (void) memcpy(&length,q,
sizeof(length));
639 q+=(ptrdiff_t)
sizeof(length);
640 p=GetVirtualPixels(image,region.x,region.y,region.width,region.height,
642 if (p == (
const Quantum *) NULL)
644 metacontent=(
const unsigned char *) GetVirtualMetacontent(image);
645 count=dpc_send(file,length,metacontent);
646 if (count != (MagickOffsetType) length)
651static MagickBooleanType ReadDistributeCachePixels(
SplayTreeInfo *registry,
661 key = (MagickAddressType) session_key;
673 message[MagickPathExtent],
679 image=(
Image *) GetValueFromSplayTree(registry,(
const void *) key);
680 if (image == (
Image *) NULL)
682 length=
sizeof(region.width)+
sizeof(region.height)+
sizeof(region.x)+
683 sizeof(region.y)+
sizeof(length);
684 count=dpc_read(file,length,message);
685 if (count != (MagickOffsetType) length)
688 (void) memcpy(®ion.width,q,
sizeof(region.width));
689 q+=(ptrdiff_t)
sizeof(region.width);
690 (void) memcpy(®ion.height,q,
sizeof(region.height));
691 q+=(ptrdiff_t)
sizeof(region.height);
692 (void) memcpy(®ion.x,q,
sizeof(region.x));
693 q+=(ptrdiff_t)
sizeof(region.x);
694 (void) memcpy(®ion.y,q,
sizeof(region.y));
695 q+=(ptrdiff_t)
sizeof(region.y);
696 (void) memcpy(&length,q,
sizeof(length));
697 q+=(ptrdiff_t)
sizeof(length);
698 p=GetVirtualPixels(image,region.x,region.y,region.width,region.height,
700 if (p == (
const Quantum *) NULL)
702 count=dpc_send(file,length,p);
703 if (count != (MagickOffsetType) length)
708static void *RelinquishImageRegistry(
void *image)
710 return((
void *) DestroyImageList((
Image *) image));
713static MagickBooleanType WriteDistributeCacheMetacontent(
721 key = (MagickAddressType) session_key;
736 message[MagickPathExtent],
744 image=(
Image *) GetValueFromSplayTree(registry,(
const void *) key);
745 if (image == (
Image *) NULL)
747 length=
sizeof(region.width)+
sizeof(region.height)+
sizeof(region.x)+
748 sizeof(region.y)+
sizeof(length);
749 count=dpc_read(file,length,message);
750 if (count != (MagickOffsetType) length)
753 (void) memcpy(®ion.width,p,
sizeof(region.width));
754 p+=(ptrdiff_t)
sizeof(region.width);
755 (void) memcpy(®ion.height,p,
sizeof(region.height));
756 p+=(ptrdiff_t)
sizeof(region.height);
757 (void) memcpy(®ion.x,p,
sizeof(region.x));
758 p+=(ptrdiff_t)
sizeof(region.x);
759 (void) memcpy(®ion.y,p,
sizeof(region.y));
760 p+=(ptrdiff_t)
sizeof(region.y);
761 (void) memcpy(&length,p,
sizeof(length));
762 p+=(ptrdiff_t)
sizeof(length);
763 q=GetAuthenticPixels(image,region.x,region.y,region.width,region.height,
765 if (q == (Quantum *) NULL)
767 metacontent=(
unsigned char *) GetAuthenticMetacontent(image);
768 count=dpc_read(file,length,metacontent);
769 if (count != (MagickOffsetType) length)
771 return(SyncAuthenticPixels(image,exception));
774static MagickBooleanType WriteDistributeCachePixels(
SplayTreeInfo *registry,
781 key = (MagickAddressType) session_key;
796 message[MagickPathExtent],
802 image=(
Image *) GetValueFromSplayTree(registry,(
const void *) key);
803 if (image == (
Image *) NULL)
805 length=
sizeof(region.width)+
sizeof(region.height)+
sizeof(region.x)+
806 sizeof(region.y)+
sizeof(length);
807 count=dpc_read(file,length,message);
808 if (count != (MagickOffsetType) length)
811 (void) memcpy(®ion.width,p,
sizeof(region.width));
812 p+=(ptrdiff_t)
sizeof(region.width);
813 (void) memcpy(®ion.height,p,
sizeof(region.height));
814 p+=(ptrdiff_t)
sizeof(region.height);
815 (void) memcpy(®ion.x,p,
sizeof(region.x));
816 p+=(ptrdiff_t)
sizeof(region.x);
817 (void) memcpy(®ion.y,p,
sizeof(region.y));
818 p+=(ptrdiff_t)
sizeof(region.y);
819 (void) memcpy(&length,p,
sizeof(length));
820 p+=(ptrdiff_t)
sizeof(length);
821 q=GetAuthenticPixels(image,region.x,region.y,region.width,region.height,
823 if (q == (Quantum *) NULL)
825 count=dpc_read(file,length,(
unsigned char *) q);
826 if (count != (MagickOffsetType) length)
828 return(SyncAuthenticPixels(image,exception));
831static HANDLER_RETURN_TYPE DistributePixelCacheClient(
void *socket)
840 status = MagickFalse;
864 shared_secret=GetPolicyValue(
"cache:shared-secret");
865 if (shared_secret == (
char *) NULL)
866 ThrowFatalException(CacheFatalError,
"shared secret required");
867 nonce=StringToStringInfo(shared_secret);
868 shared_secret=DestroyString(shared_secret);
869 session_key=GetMagickSignature(nonce);
870 nonce=DestroyStringInfo(nonce);
871 exception=AcquireExceptionInfo();
875 registry=NewSplayTree((
int (*)(
const void *,
const void *)) NULL,
876 (
void *(*)(
void *)) NULL,RelinquishImageRegistry);
877 client_socket=(*(SOCKET_TYPE *) socket);
878 count=dpc_send(client_socket,
sizeof(session_key),&session_key);
879 for (status=MagickFalse; ; )
881 count=dpc_read(client_socket,1,(
unsigned char *) &command);
884 count=dpc_read(client_socket,
sizeof(key),(
unsigned char *) &key);
885 if ((count != (MagickOffsetType)
sizeof(key)) || (key != session_key))
891 status=OpenDistributeCache(registry,client_socket,session_key,
893 count=dpc_send(client_socket,
sizeof(status),&status);
898 status=ReadDistributeCachePixels(registry,client_socket,session_key,
904 status=ReadDistributeCacheMetacontent(registry,client_socket,
905 session_key,exception);
910 status=WriteDistributeCachePixels(registry,client_socket,session_key,
916 status=WriteDistributeCacheMetacontent(registry,client_socket,
917 session_key,exception);
922 status=DestroyDistributeCache(registry,session_key);
928 if (status == MagickFalse)
933 count=dpc_send(client_socket,
sizeof(status),&status);
934 CLOSE_SOCKET(client_socket);
935 exception=DestroyExceptionInfo(exception);
936 registry=DestroySplayTree(registry);
937 return(HANDLER_RETURN_VALUE);
940MagickExport
void DistributePixelCacheServer(
const int port,
944 service[MagickPathExtent];
949#if defined(MAGICKCORE_THREAD_SUPPORT)
955#elif defined(_MSC_VER)
979 assert(exception->signature == MagickCoreSignature);
980 magick_unreferenced(exception);
981#if defined(MAGICKCORE_HAVE_WINSOCK2)
982 InitializeWinsock2(MagickFalse);
984 (void) memset(&hint,0,
sizeof(hint));
985 hint.ai_family=AF_INET;
986 hint.ai_socktype=SOCK_STREAM;
987 hint.ai_flags=AI_PASSIVE;
988 (void) FormatLocaleString(service,MagickPathExtent,
"%d",port);
989 status=getaddrinfo((
const char *) NULL,service,&hint,&result);
991 ThrowFatalException(CacheFatalError,
"UnableToListen");
992 server_socket=(SOCKET_TYPE) 0;
993 for (p=result; p != (
struct addrinfo *) NULL; p=p->ai_next)
998 server_socket=socket(p->ai_family,p->ai_socktype,p->ai_protocol);
999 if (server_socket == -1)
1002 status=setsockopt(server_socket,SOL_SOCKET,SO_REUSEADDR,(
char *) &one,
1003 (socklen_t)
sizeof(one));
1006 CLOSE_SOCKET(server_socket);
1009 status=bind(server_socket,p->ai_addr,(socklen_t) p->ai_addrlen);
1012 CLOSE_SOCKET(server_socket);
1017 if (p == (
struct addrinfo *) NULL)
1018 ThrowFatalException(CacheFatalError,
"UnableToBind");
1019 freeaddrinfo(result);
1020 status=listen(server_socket,DPCPendingConnections);
1022 ThrowFatalException(CacheFatalError,
"UnableToListen");
1023#if defined(MAGICKCORE_THREAD_SUPPORT)
1024 pthread_attr_init(&attributes);
1034 length=(socklen_t)
sizeof(address);
1035 client_socket=accept(server_socket,(
struct sockaddr *) &address,&length);
1036 if (client_socket == -1)
1037 ThrowFatalException(CacheFatalError,
"UnableToEstablishConnection");
1038#if defined(MAGICKCORE_THREAD_SUPPORT)
1039 status=pthread_create(&threads,&attributes,DistributePixelCacheClient,
1040 (
void *) &client_socket);
1042 ThrowFatalException(CacheFatalError,
"UnableToCreateClientThread");
1043#elif defined(_MSC_VER)
1044 if (CreateThread(0,0,DistributePixelCacheClient,(
void*) &client_socket,0,&threadID) == (HANDLE) NULL)
1045 ThrowFatalException(CacheFatalError,
"UnableToCreateClientThread");
1067MagickPrivate
void DistributeCacheTerminus(
void)
1069#ifdef MAGICKCORE_HAVE_WINSOCK2
1071 ActivateSemaphoreInfo(&winsock2_semaphore);
1072 LockSemaphoreInfo(winsock2_semaphore);
1073 if (wsaData != (WSADATA *) NULL)
1076 wsaData=(WSADATA *) RelinquishMagickMemory((
void *) wsaData);
1078 UnlockSemaphoreInfo(winsock2_semaphore);
1079 RelinquishSemaphoreInfo(&winsock2_semaphore);
1109 assert(server_info->signature == MagickCoreSignature);
1110 return(server_info->file);
1137MagickPrivate
const char *GetDistributeCacheHostname(
1141 assert(server_info->signature == MagickCoreSignature);
1142 return(server_info->hostname);
1171 assert(server_info->signature == MagickCoreSignature);
1172 return(server_info->port);
1200MagickPrivate MagickBooleanType OpenDistributePixelCache(
1210 message[MagickPathExtent],
1217 assert(server_info->signature == MagickCoreSignature);
1218 assert(image != (
Image *) NULL);
1219 assert(image->signature == MagickCoreSignature);
1225 (void) memcpy(p,&server_info->session_key,
sizeof(server_info->session_key));
1226 p+=(ptrdiff_t)
sizeof(server_info->session_key);
1227 (void) memcpy(p,&image->storage_class,
sizeof(image->storage_class));
1228 p+=(ptrdiff_t)
sizeof(image->storage_class);
1229 (void) memcpy(p,&image->colorspace,
sizeof(image->colorspace));
1230 p+=(ptrdiff_t)
sizeof(image->colorspace);
1231 (void) memcpy(p,&image->alpha_trait,
sizeof(image->alpha_trait));
1232 p+=(ptrdiff_t)
sizeof(image->alpha_trait);
1233 (void) memcpy(p,&image->channels,
sizeof(image->channels));
1234 p+=(ptrdiff_t)
sizeof(image->channels);
1235 (void) memcpy(p,&image->columns,
sizeof(image->columns));
1236 p+=(ptrdiff_t)
sizeof(image->columns);
1237 (void) memcpy(p,&image->rows,
sizeof(image->rows));
1238 p+=(ptrdiff_t)
sizeof(image->rows);
1239 (void) memcpy(p,&image->number_channels,
sizeof(image->number_channels));
1240 p+=(ptrdiff_t)
sizeof(image->number_channels);
1241 (void) memcpy(p,image->channel_map,MaxPixelChannels*
1242 sizeof(*image->channel_map));
1243 p+=(ptrdiff_t) MaxPixelChannels*
sizeof(*image->channel_map);
1244 (void) memcpy(p,&image->metacontent_extent,
sizeof(image->metacontent_extent));
1245 p+=(ptrdiff_t)
sizeof(image->metacontent_extent);
1246 count=dpc_send(server_info->file,(MagickSizeType) (p-message),message);
1247 if (count != (MagickOffsetType) (p-message))
1248 return(MagickFalse);
1250 count=dpc_read(server_info->file,
sizeof(status),(
unsigned char *) &status);
1251 if (count != (MagickOffsetType)
sizeof(status))
1252 return(MagickFalse);
1289MagickPrivate MagickOffsetType ReadDistributePixelCacheMetacontent(
1291 const MagickSizeType length,
unsigned char *metacontent)
1297 message[MagickPathExtent],
1304 assert(server_info->signature == MagickCoreSignature);
1306 assert(metacontent != (
unsigned char *) NULL);
1307 if (length > (MagickSizeType) MAGICK_SSIZE_MAX)
1311 (void) memcpy(p,&server_info->session_key,
sizeof(server_info->session_key));
1312 p+=(ptrdiff_t)
sizeof(server_info->session_key);
1313 (void) memcpy(p,®ion->width,
sizeof(region->width));
1314 p+=(ptrdiff_t)
sizeof(region->width);
1315 (void) memcpy(p,®ion->height,
sizeof(region->height));
1316 p+=(ptrdiff_t)
sizeof(region->height);
1317 (void) memcpy(p,®ion->x,
sizeof(region->x));
1318 p+=(ptrdiff_t)
sizeof(region->x);
1319 (void) memcpy(p,®ion->y,
sizeof(region->y));
1320 p+=(ptrdiff_t)
sizeof(region->y);
1321 (void) memcpy(p,&length,
sizeof(length));
1322 p+=(ptrdiff_t)
sizeof(length);
1323 count=dpc_send(server_info->file,(MagickSizeType) (p-message),message);
1324 if (count != (MagickOffsetType) (p-message))
1326 return(dpc_read(server_info->file,length,metacontent));
1362MagickPrivate MagickOffsetType ReadDistributePixelCachePixels(
1364 const MagickSizeType length,
unsigned char *magick_restrict pixels)
1370 message[MagickPathExtent],
1377 assert(server_info->signature == MagickCoreSignature);
1379 assert(pixels != (
unsigned char *) NULL);
1380 if (length > (MagickSizeType) MAGICK_SSIZE_MAX)
1384 (void) memcpy(p,&server_info->session_key,
sizeof(server_info->session_key));
1385 p+=(ptrdiff_t)
sizeof(server_info->session_key);
1386 (void) memcpy(p,®ion->width,
sizeof(region->width));
1387 p+=(ptrdiff_t)
sizeof(region->width);
1388 (void) memcpy(p,®ion->height,
sizeof(region->height));
1389 p+=(ptrdiff_t)
sizeof(region->height);
1390 (void) memcpy(p,®ion->x,
sizeof(region->x));
1391 p+=(ptrdiff_t)
sizeof(region->x);
1392 (void) memcpy(p,®ion->y,
sizeof(region->y));
1393 p+=(ptrdiff_t)
sizeof(region->y);
1394 (void) memcpy(p,&length,
sizeof(length));
1395 p+=(ptrdiff_t)
sizeof(length);
1396 count=dpc_send(server_info->file,(MagickSizeType) (p-message),message);
1397 if (count != (MagickOffsetType) (p-message))
1399 return(dpc_read(server_info->file,length,pixels));
1426MagickPrivate MagickBooleanType RelinquishDistributePixelCache(
1436 message[MagickPathExtent],
1443 assert(server_info->signature == MagickCoreSignature);
1446 (void) memcpy(p,&server_info->session_key,
sizeof(server_info->session_key));
1447 p+=(ptrdiff_t)
sizeof(server_info->session_key);
1448 count=dpc_send(server_info->file,(MagickSizeType) (p-message),message);
1449 if (count != (MagickOffsetType) (p-message))
1450 return(MagickFalse);
1452 count=dpc_read(server_info->file,
sizeof(status),(
unsigned char *) &status);
1453 if (count != (MagickOffsetType)
sizeof(status))
1454 return(MagickFalse);
1491MagickPrivate MagickOffsetType WriteDistributePixelCacheMetacontent(
1493 const MagickSizeType length,
const unsigned char *metacontent)
1499 message[MagickPathExtent],
1506 assert(server_info->signature == MagickCoreSignature);
1508 assert(metacontent != (
unsigned char *) NULL);
1509 if (length > (MagickSizeType) MAGICK_SSIZE_MAX)
1513 (void) memcpy(p,&server_info->session_key,
sizeof(server_info->session_key));
1514 p+=(ptrdiff_t)
sizeof(server_info->session_key);
1515 (void) memcpy(p,®ion->width,
sizeof(region->width));
1516 p+=(ptrdiff_t)
sizeof(region->width);
1517 (void) memcpy(p,®ion->height,
sizeof(region->height));
1518 p+=(ptrdiff_t)
sizeof(region->height);
1519 (void) memcpy(p,®ion->x,
sizeof(region->x));
1520 p+=(ptrdiff_t)
sizeof(region->x);
1521 (void) memcpy(p,®ion->y,
sizeof(region->y));
1522 p+=(ptrdiff_t)
sizeof(region->y);
1523 (void) memcpy(p,&length,
sizeof(length));
1524 p+=(ptrdiff_t)
sizeof(length);
1525 count=dpc_send(server_info->file,(MagickSizeType) (p-message),message);
1526 if (count != (MagickOffsetType) (p-message))
1528 return(dpc_send(server_info->file,length,metacontent));
1565MagickPrivate MagickOffsetType WriteDistributePixelCachePixels(
1567 const MagickSizeType length,
const unsigned char *magick_restrict pixels)
1573 message[MagickPathExtent],
1580 assert(server_info->signature == MagickCoreSignature);
1582 assert(pixels != (
const unsigned char *) NULL);
1583 if (length > (MagickSizeType) MAGICK_SSIZE_MAX)
1587 (void) memcpy(p,&server_info->session_key,
sizeof(server_info->session_key));
1588 p+=(ptrdiff_t)
sizeof(server_info->session_key);
1589 (void) memcpy(p,®ion->width,
sizeof(region->width));
1590 p+=(ptrdiff_t)
sizeof(region->width);
1591 (void) memcpy(p,®ion->height,
sizeof(region->height));
1592 p+=(ptrdiff_t)
sizeof(region->height);
1593 (void) memcpy(p,®ion->x,
sizeof(region->x));
1594 p+=(ptrdiff_t)
sizeof(region->x);
1595 (void) memcpy(p,®ion->y,
sizeof(region->y));
1596 p+=(ptrdiff_t)
sizeof(region->y);
1597 (void) memcpy(p,&length,
sizeof(length));
1598 p+=(ptrdiff_t)
sizeof(length);
1599 count=dpc_send(server_info->file,(MagickSizeType) (p-message),message);
1600 if (count != (MagickOffsetType) (p-message))
1602 return(dpc_send(server_info->file,length,pixels));