graphicsmagick-apis Mailing List for GraphicsMagick
Swiss army knife of image processing
Brought to you by:
bfriesen
You can subscribe to this list here.
2003 |
Jan
|
Feb
|
Mar
(23) |
Apr
(44) |
May
(19) |
Jun
(28) |
Jul
(15) |
Aug
(30) |
Sep
(5) |
Oct
(14) |
Nov
(13) |
Dec
(20) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2004 |
Jan
(4) |
Feb
(5) |
Mar
(17) |
Apr
(17) |
May
(1) |
Jun
|
Jul
|
Aug
(9) |
Sep
(12) |
Oct
(22) |
Nov
(9) |
Dec
(14) |
2005 |
Jan
(18) |
Feb
(2) |
Mar
(18) |
Apr
(5) |
May
(2) |
Jun
|
Jul
(2) |
Aug
(4) |
Sep
(2) |
Oct
(6) |
Nov
(2) |
Dec
(2) |
2006 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(3) |
Nov
(1) |
Dec
|
2007 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(5) |
Nov
|
Dec
|
2008 |
Jan
|
Feb
|
Mar
|
Apr
(1) |
May
|
Jun
(3) |
Jul
|
Aug
|
Sep
|
Oct
(1) |
Nov
(1) |
Dec
(2) |
2009 |
Jan
(1) |
Feb
|
Mar
|
Apr
|
May
(1) |
Jun
|
Jul
(2) |
Aug
|
Sep
(1) |
Oct
(9) |
Nov
(3) |
Dec
(1) |
2010 |
Jan
(4) |
Feb
|
Mar
(9) |
Apr
(3) |
May
|
Jun
|
Jul
(1) |
Aug
(1) |
Sep
|
Oct
|
Nov
|
Dec
|
2011 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(18) |
Jun
(23) |
Jul
|
Aug
(22) |
Sep
(1) |
Oct
(9) |
Nov
|
Dec
|
2012 |
Jan
(8) |
Feb
(3) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(7) |
Oct
|
Nov
(2) |
Dec
|
2013 |
Jan
(9) |
Feb
|
Mar
|
Apr
(12) |
May
|
Jun
(5) |
Jul
(5) |
Aug
|
Sep
(3) |
Oct
|
Nov
(4) |
Dec
|
2014 |
Jan
(8) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(4) |
Sep
(8) |
Oct
|
Nov
|
Dec
(4) |
2015 |
Jan
(1) |
Feb
|
Mar
|
Apr
(1) |
May
|
Jun
|
Jul
|
Aug
|
Sep
(3) |
Oct
|
Nov
|
Dec
|
2016 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(2) |
2017 |
Jan
(2) |
Feb
(4) |
Mar
(2) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2020 |
Jan
|
Feb
(16) |
Mar
(69) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2021 |
Jan
|
Feb
(4) |
Mar
(2) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Bob F. <bfr...@si...> - 2021-03-08 15:11:51
|
On Mon, 8 Mar 2021, Lukas Studer wrote: > > I did notice though that setting the "subimage" and "subrange" > attributes in ImageInfo was significantly slower than using the file > name specifier. Do you have any idea as to why this might be? I have no idea other than if for some reason Ghostscript is being invoked more often or that something you are doing is causing more RAM to be consumed. > On a slightly different topic: It appears that the writing of PDF files > suffers the same limitations as the reading thereof. Writing large > documents causes the RAM to overflow crashing the application. Do you > have any insights on how to keep the RAM usage in check while writing > the PDF files? Is there a way to write them in chunks? Further, I don't > quite understand why this happens in general. How is it that a PDF file > of about 100MB can overflow my RAM of about 64GB (when > importing/exporting at 300 DPI). Is there something I'm doing horribly > wrong? Why is it bloated this much? The internal image model used by GraphicsMagick (inherited from ImageMagick) is not very efficient. The documentation in www/INSTALL-unix.rst says that the memory usage for an image may be computed as: (QuantumDepth*Rows*Columns*5)/8 Notice that QuantumDepth is a constant for the build ("Q8", "Q16", "Q32") and that the memory required for one pixel has no relationship with how the pixels may be stored in a file. Your PDF files might use just a single bit (where one byte can store 8 bits) to represent a pixel (for black/white). Furthermore, the PDF file may use extremely effective compression so that many pixels may be stored in very little space. While the simple representation in memory simplifies things and reduces the amount of implementation code required, it is grossly inefficient as pertains to memory usage. Even the Q8 build may consume 5 bytes of memory to store one bilevel pixel. The format writer suffers from some of the same issues as the reader. All of the frames need to be built up in memory (or also as temporary disk files) before the writer writes anything. There are two major issues to solve in GraphicsMagick (but also in ImageMagick in case you were wondering) in order to reduce the memory consumption for each pixel, but also to be able to "stream" image frames from the source to the destination. Bob -- Bob Friesenhahn bfr...@si..., http://www.simplesystems.org/users/bfriesen/ GraphicsMagick Maintainer, http://www.GraphicsMagick.org/ Public Key, http://www.simplesystems.org/users/bfriesen/public-key.txt |
From: Lukas S. <luk...@bf...> - 2021-03-08 14:46:45
|
Hi Bob, I managed to get a chunked, parallel import of large PDF files working using OpenMP and the index-of like operator in the file name specifier as you suggested. I also overloaded the readImages function adding a read arguments struct to set some attributes in the image info struct (see code below). Using this I can now also override the density for the import. I noticed this was also flagged with "FIXME". typedef struct ReadArgs { int subimage = -1; int subrange = -1; const std::string density = ""; } ReadArgs; template <class Container> void readImages( Container *sequence_, const std::string &imageSpec_, ReadArgs args = {}) { MagickLib::ImageInfo *imageInfo = MagickLib::CloneImageInfo(0); imageSpec_.copy( imageInfo->filename, MaxTextExtent-1 ); imageInfo->filename[ imageSpec_.length() ] = 0; if (args.subimage >= 0) imageInfo->subimage = args.subimage; if (args.subrange >= 0) imageInfo->subrange = args.subrange; if (args.density != "") { imageInfo->density = (char *) malloc(args.density.length()); std::strcpy(imageInfo->density, args.density.c_str()); imageInfo->density[ args.density.length() ] = 0; } MagickLib::ExceptionInfo exceptionInfo; MagickLib::GetExceptionInfo( &exceptionInfo ); MagickLib::Image* images = MagickLib::ReadImage( imageInfo, &exceptionInfo ); MagickLib::DestroyImageInfo(imageInfo); insertImages( sequence_, images); throwException( exceptionInfo ); } I did notice though that setting the "subimage" and "subrange" attributes in ImageInfo was significantly slower than using the file name specifier. Do you have any idea as to why this might be? On a slightly different topic: It appears that the writing of PDF files suffers the same limitations as the reading thereof. Writing large documents causes the RAM to overflow crashing the application. Do you have any insights on how to keep the RAM usage in check while writing the PDF files? Is there a way to write them in chunks? Further, I don't quite understand why this happens in general. How is it that a PDF file of about 100MB can overflow my RAM of about 64GB (when importing/exporting at 300 DPI). Is there something I'm doing horribly wrong? Why is it bloated this much? Thanks for your help! Cheers, Lukas On 10.02.21 15:08, Bob Friesenhahn wrote: > On Tue, 9 Feb 2021, Lukas Studer wrote: >> >> I will have a look at your suggestions and see which solution suits my >> needs best. > > I forgot of something which may help solve the problem for you. The > starting page offset and range may be specified as part of the input > file name. This means that you can already use it to request a range > of pages using the existing implementation. > > So, you can request 'file.pdf[0-9]', and then 'file.pdf[10-19]', etc. > in order to keep the number of pages requested at one time down to a > manageable level. > > Bob |
From: Bob F. <bfr...@si...> - 2021-02-10 14:08:25
|
On Tue, 9 Feb 2021, Lukas Studer wrote: > > I will have a look at your suggestions and see which solution suits my > needs best. I forgot of something which may help solve the problem for you. The starting page offset and range may be specified as part of the input file name. This means that you can already use it to request a range of pages using the existing implementation. So, you can request 'file.pdf[0-9]', and then 'file.pdf[10-19]', etc. in order to keep the number of pages requested at one time down to a manageable level. Bob -- Bob Friesenhahn bfr...@si..., http://www.simplesystems.org/users/bfriesen/ GraphicsMagick Maintainer, http://www.GraphicsMagick.org/ Public Key, http://www.simplesystems.org/users/bfriesen/public-key.txt |
From: Lukas S. <luk...@bf...> - 2021-02-09 15:20:18
|
Hello Bob, Thank you for this super quick and detailed replay. I will have a look at your suggestions and see which solution suits my needs best. Thank you very much and cheers, Lukas On 09.02.21 15:54, Bob Friesenhahn wrote: > On Tue, 9 Feb 2021, Lukas Studer wrote: >> >> First of all, I'm new to GraphicsMagick and the management thereof, so I >> am not quite sure if this is the correct mailing list. >> >> I'm am using the Magick++ API to read large PDF files (ballpark of about >> 2000 to 3000 pages, size of 100MB and upwards) and store each page in a >> database (not shown in snippet). While doing so I run into resource >> issues, namely not enough RAM, when reading the PDF file resulting in >> basically, or what feels like, an infinite runtime. > > You are facing a long-term design issue regarding the interfacing of > GraphicsMagick and Ghostscript as well as how GraphicsMagick works in > general. GraphicsMagick asks Ghostscript to convert all (or a range) > of pages to an intermediate file format (e.g. a PNM sub-format) and > then reads all of the pages before it writes any output. This > approach does not scale since the system will run out of resources. > >> My question now boils down to, what is the proper API for such a use >> case, i.e. how does one handle such big PDF files using the Magick++ >> API? Is there a way to do this in batches or in a streamed fashion, >> where I read page by page and directly store them? > > It is possible to succeed by iteratively setting the 'subimage' and > 'subrange' properties so that only a few pages are included in the > conversion at a time. It turns out that Ghostscript is pretty > efficient at finding the first specified page in a PDF sequence. > >> I know of the syntax involving the indexOf operator to only read a range >> of pages, e.g. "myFile.pdf[0-100]". I was hoping to solve the issue >> directly via the Magick++ API. > > Given the advice to set the 'subimage' and 'subrange' properties you > would be able to succeed, but then the next problem is hit in that I > see this FIXME: statement at the top of the readImages() > implementation in Magick++/STL.h: > > "FIXME: need a way to specify options like size, depth, and density." > > The FIXME: statement should also have mentioned 'subimage' and > 'subrange'. > > There is yet hope given that the readImages() template function is in > a header file and is very short so a modified implementation can be > added. The next trick is that the Magick::Options implementation is > described as "This is an internal implementation class and is not part > of the Magick++ API" so it can't be used. There are also > subImageImage() and subRangeImage() STL function objects, but they are > not intended for this purpose. > > Ultimately, what is needed is to update 'subimage' and 'subrange' in > this ImageInfo instance similar to how filename is updated. > > MagickLib::ImageInfo *imageInfo = MagickLib::CloneImageInfo(0); > > So, what can be done is to duplicate the existing readImages() > template function and create a new one with two more integer arguments > for 'subimage' and 'subrange'. Then assign those arguments into the > ImageInfo struct. This would allow you to request a reasonable number > of pages at a time. The last tricky thing is to detect when the end > of the document has been reached. If just one page at a time is > requested, then this is not so hard, but it is less efficient than > several pages at a time. Perhaps when an error occurs, then switch to > one page at a time. A more sophisticated readImages() could add a > loop so that the implementation does the per-page iteration itself. > > Lastly, there is a completely different solution, which is to ignore > the existing STL implementation. Instead, use the Image class and its > read method which is only willing to read one image at a time from the > sequence. The Image class provides subImage() and subRange() so you > should be able to read one page at a time. > > I apologize for such a lame implementation. > > Bob |
From: Bob F. <bfr...@si...> - 2021-02-09 14:54:23
|
On Tue, 9 Feb 2021, Lukas Studer wrote: > > First of all, I'm new to GraphicsMagick and the management thereof, so I > am not quite sure if this is the correct mailing list. > > I'm am using the Magick++ API to read large PDF files (ballpark of about > 2000 to 3000 pages, size of 100MB and upwards) and store each page in a > database (not shown in snippet). While doing so I run into resource > issues, namely not enough RAM, when reading the PDF file resulting in > basically, or what feels like, an infinite runtime. You are facing a long-term design issue regarding the interfacing of GraphicsMagick and Ghostscript as well as how GraphicsMagick works in general. GraphicsMagick asks Ghostscript to convert all (or a range) of pages to an intermediate file format (e.g. a PNM sub-format) and then reads all of the pages before it writes any output. This approach does not scale since the system will run out of resources. > My question now boils down to, what is the proper API for such a use > case, i.e. how does one handle such big PDF files using the Magick++ > API? Is there a way to do this in batches or in a streamed fashion, > where I read page by page and directly store them? It is possible to succeed by iteratively setting the 'subimage' and 'subrange' properties so that only a few pages are included in the conversion at a time. It turns out that Ghostscript is pretty efficient at finding the first specified page in a PDF sequence. > I know of the syntax involving the indexOf operator to only read a range > of pages, e.g. "myFile.pdf[0-100]". I was hoping to solve the issue > directly via the Magick++ API. Given the advice to set the 'subimage' and 'subrange' properties you would be able to succeed, but then the next problem is hit in that I see this FIXME: statement at the top of the readImages() implementation in Magick++/STL.h: "FIXME: need a way to specify options like size, depth, and density." The FIXME: statement should also have mentioned 'subimage' and 'subrange'. There is yet hope given that the readImages() template function is in a header file and is very short so a modified implementation can be added. The next trick is that the Magick::Options implementation is described as "This is an internal implementation class and is not part of the Magick++ API" so it can't be used. There are also subImageImage() and subRangeImage() STL function objects, but they are not intended for this purpose. Ultimately, what is needed is to update 'subimage' and 'subrange' in this ImageInfo instance similar to how filename is updated. MagickLib::ImageInfo *imageInfo = MagickLib::CloneImageInfo(0); So, what can be done is to duplicate the existing readImages() template function and create a new one with two more integer arguments for 'subimage' and 'subrange'. Then assign those arguments into the ImageInfo struct. This would allow you to request a reasonable number of pages at a time. The last tricky thing is to detect when the end of the document has been reached. If just one page at a time is requested, then this is not so hard, but it is less efficient than several pages at a time. Perhaps when an error occurs, then switch to one page at a time. A more sophisticated readImages() could add a loop so that the implementation does the per-page iteration itself. Lastly, there is a completely different solution, which is to ignore the existing STL implementation. Instead, use the Image class and its read method which is only willing to read one image at a time from the sequence. The Image class provides subImage() and subRange() so you should be able to read one page at a time. I apologize for such a lame implementation. Bob -- Bob Friesenhahn bfr...@si..., http://www.simplesystems.org/users/bfriesen/ GraphicsMagick Maintainer, http://www.GraphicsMagick.org/ Public Key, http://www.simplesystems.org/users/bfriesen/public-key.txt |
From: Lukas S. <luk...@bf...> - 2021-02-09 10:38:40
|
Hello, First of all, I'm new to GraphicsMagick and the management thereof, so I am not quite sure if this is the correct mailing list. I'm am using the Magick++ API to read large PDF files (ballpark of about 2000 to 3000 pages, size of 100MB and upwards) and store each page in a database (not shown in snippet). While doing so I run into resource issues, namely not enough RAM, when reading the PDF file resulting in basically, or what feels like, an infinite runtime. My question now boils down to, what is the proper API for such a use case, i.e. how does one handle such big PDF files using the Magick++ API? Is there a way to do this in batches or in a streamed fashion, where I read page by page and directly store them? I know of the syntax involving the indexOf operator to only read a range of pages, e.g. "myFile.pdf[0-100]". I was hoping to solve the issue directly via the Magick++ API. Snippet: std::string Database::importPDF(const std::string& pdfPath, const std::string& name) { std::ifstream inputFile(pdfPath); if (!inputFile.good()) return ""; // get current date and time in iso format std::locale::global(std::locale("")); std::chrono::system_clock::time_point now = std::chrono::system_clock::now(); std::time_t t = std::chrono::system_clock::to_time_t(now); char dateBuff[100]; std::strftime(dateBuff, sizeof(dateBuff), "%F", std::localtime(&t)); Magick::InitializeMagick(""); std::list<Magick::Image> images; Magick::readImages(&images, pdfPath); size_t i; unsigned int j = 0; std::list<Magick::Image>::iterator image; for (image = images.begin(), i = 0; image != images.end(); image++, i++, j++) { Magick::Blob imageData; image->magick("PNG"); image->write(&imageData); this->addPage("", imageData.base64(), image->rows(), image->columns(), j, 0, i+1, images.size(), 0); } return pdfPath; } Thanks and Cheers, Lukas |
From: 10bxjfhf <10b...@te...> - 2020-03-26 18:42:24
|
On 2020-03-26 7:20 a.m., Bob Friesenhahn wrote: > On Wed, 25 Mar 2020, 10bxjfhf wrote: >> Deleting or renaming the log.mgk files did not always seem to help. >> IIRC, it will simply use the built-in defaults if it does not manage >> to find log.mgk and that is cast in stone once compiled. > > The functions I recently added allow you to change the "built-in > defaults" before invoking InitializeMagick(). All is good right now for logging as far as I have tested it - see below > I don't understand "a lot of work". >> >> I must call >> >> InitializeMagick(NULL); >> MagickLib::DestroyMagick(); >> >> and let it go through its gyrations; then initialize the library >> again, just to be able to implement the necessary environment >> variables, independent of any other app I might have installed, and >> to allow me to override some of the built-in defaults. > > Isn't this "a lot of work" due to the automatic DLL initialization > that you are easily able to disable and is now disabled by default? From your earlier message from 2020-03-23, 12:32 p.m In the mean time, this sequence should work: InitializeMagick(NULL); DestroyMagick(); [ Do some defaults configuration ] InitializeMagick(NULL); After cloning the latest version of GM and running configure, I checked to make sure ProvideDllMain was disabled when I built my current app. Just now, I tried to run my app without the first two lines and all worked as expected. So, yes, if ProvideDllMain is not disabled, I (probably) would have to jump through those extra hoops - my misunderstanding Again, thank you for the mods and your help; I think I'll be good for a while - at least I hope so :-) Arnold |
From: Bob F. <bfr...@si...> - 2020-03-26 14:20:22
|
On Wed, 25 Mar 2020, 10bxjfhf wrote: > Deleting or renaming the log.mgk files did not always seem to help. IIRC, it > will simply use the built-in defaults if it does not manage to find log.mgk > and that is cast in stone once compiled. The functions I recently added allow you to change the "built-in defaults" before invoking InitializeMagick(). >> I don't understand "a lot of work". > > I must call > > InitializeMagick(NULL); > MagickLib::DestroyMagick(); > > and let it go through its gyrations; then initialize the library again, just > to be able to implement the necessary environment variables, independent of > any other app I might have installed, and to allow me to override some of the > built-in defaults. Isn't this "a lot of work" due to the automatic DLL initialization that you are easily able to disable and is now disabled by default? Bob -- Bob Friesenhahn bfr...@si..., http://www.simplesystems.org/users/bfriesen/ GraphicsMagick Maintainer, http://www.GraphicsMagick.org/ Public Key, http://www.simplesystems.org/users/bfriesen/public-key.txt |
From: 10bxjfhf <10b...@te...> - 2020-03-26 01:45:21
|
On 2020-03-25 1:37 p.m., Bob Friesenhahn wrote: > On Wed, 25 Mar 2020, 10bxjfhf wrote: > >> That then seems to imply that I should not need anything but to set >> the call back; any other log.mgk would be ignored and I really would >> not need the dummy calls to Initialize & DestroyMagick at all? > > As I recall, the problem you were solving was that the DLL was calling > InitializeMagick() and you desire to obtain configuration tracing > using your own rules. Yes & no. I focused on the log functionality because things did not work for me as expected and I had to sort out why not, what I could do to get a handle on what I was not doing the way the library expected it to be done in very general terms. Without getting useful feedback from the code I am trying to use, helping me to figure where I am not doing the 'right' thing, will only encourage me to give up in frustration. From my current experience, Magick is the only library I can recall which is so very dependent on external files that have to be manually fine tuned just to find out what is going wrong. Don't get me wrong. GM looks like a well maintained and well thought out set of libraries and utilities, but apparently most used and useful in the *.nix command line world. In my experience till now - mostly in the Windows worlds, though I did spend a few years working with Solaris & DOS :-( - options and fine tuning of even error reporting is done without manual intervention in external files. Yet even so, I can well imagine that I might find other feature useful, but would hope that I will be able to set their parameters and options more easily than by invoking an external editor. Verifying user edited text that way would be a lot of work, if at all possible. And my experience with textfile vs txtfile in log.mgk is still very vivid in my memory :-) > > It is starting to seem like we need yet another function which says to > use the logging defaults as is or to skip searching for log.mgk. A function to simply force the library to ignore log.mgk might be useful, though it ought to not interfere with the rest of the configuration files > > Of course you could just delete log.mgk, or deliver an empty log.mgk, > or remove settings from log.mkg that you don't like. The settings > from log.mgk would be merged with the existing defaults (including > those you set via the API) when logging is fully initialized. Deleting or renaming the log.mgk files did not always seem to help. IIRC, it will simply use the built-in defaults if it does not manage to find log.mgk and that is cast in stone once compiled. > >> If I could/can also set up the log events and format, I suppose that >> would work. >> >> Still, if that is needed to setup the static log data struct, a lot >> of work is done just for that. > > I don't understand "a lot of work". I must call InitializeMagick(NULL); MagickLib::DestroyMagick(); and let it go through its gyrations; then initialize the library again, just to be able to implement the necessary environment variables, independent of any other app I might have installed, and to allow me to override some of the built-in defaults. Perhaps there is a way to handle special cases with exceptions at the app level, but I have not looked at or for that at all. > If you implement a logging callback then there is more work for you > since then you need to do something with the data. In any case, make > sure that your logging callback does not block (for long) since it > would also block further operations by the thread which produced the > log, and would block other threads which might want to produce a log. Understood, though it seems a shame to circumvent all of the existing code in the library and certainly is not my preferred way of doing things. And I very much appreciate you sticking with me on this climb Arnold |
From: Bob F. <bfr...@si...> - 2020-03-25 20:37:14
|
On Wed, 25 Mar 2020, 10bxjfhf wrote: >> >> There is not currently a way to request that a log.mgk not be loaded and to >> use only the default values. > > As I understand things now, it seems you are saying the if I set up a call > back, I can send the info to any log target I chose to implement the code > for. Yes. > That then seems to imply that I should not need anything but to set the call > back; any other log.mgk would be ignored and I really would not need the > dummy calls to Initialize & DestroyMagick at all? As I recall, the problem you were solving was that the DLL was calling InitializeMagick() and you desire to obtain configuration tracing using your own rules. It is starting to seem like we need yet another function which says to use the logging defaults as is or to skip searching for log.mgk. Of course you could just delete log.mgk, or deliver an empty log.mgk, or remove settings from log.mkg that you don't like. The settings from log.mgk would be merged with the existing defaults (including those you set via the API) when logging is fully initialized. > If I could/can also set up the log events and format, I suppose that would > work. > > Still, if that is needed to setup the static log data struct, a lot of work > is done just for that. I don't understand "a lot of work". If you implement a logging callback then there is more work for you since then you need to do something with the data. In any case, make sure that your logging callback does not block (for long) since it would also block further operations by the thread which produced the log, and would block other threads which might want to produce a log. > My Hg workflow still needs refining. > > I clone the GM repos and then work in it; that seems to make it impossible to > later update or pull from the main repo. It should not be so hard. When you pull changes, it does not update files, but if you are also using Mercurial for change control, then it would produce a new "head" (a fork) which needs to be merged with your changes and then submitted to remove the new "head". Mercurial normally automatically merges changes which appear not to conflict but then brings up a merge tool which the changes might conflict and require user intervention. While Mercurial supports proper branches, within any given branch, there may only be one or two "heads" (your own "head" and a head from the other repository). If there is a second head, that means that someone else made changes which need to be integrated and commited so you can see them. The easiest way to avoid the double-headed problem is to pull remote changes before you do a commit. > Would I have to clone the main repo and then clone a second copy for me to > work in? > > or is the simplest way to start over with a new cloned work dir? Normally there should never be a reason to have to re-clone the repository in order to use it. The only times I have done this is when I realized that I did something really bad (before pushing to another repository) and it seemed easier to re-clone than to repair the harm which was caused. Bob -- Bob Friesenhahn bfr...@si..., http://www.simplesystems.org/users/bfriesen/ GraphicsMagick Maintainer, http://www.GraphicsMagick.org/ Public Key, http://www.simplesystems.org/users/bfriesen/public-key.txt |
From: 10bxjfhf <10b...@te...> - 2020-03-25 17:27:52
|
On 2020-03-25 6:53 a.m., Bob Friesenhahn wrote: > On Tue, 24 Mar 2020, 10bxjfhf wrote: >> >> During the last call, at some point the log file name gets set to my >> specified path: >> >> "C:\\Users\\arnold\\AppData\\Roaming\\wxIC-MT\\NewLogFile.log" >> >> at log.c line 354 from log_info_defaults.filename >> >> but after that, at log.c 434++ it is reset because some log.mgk is >> loaded because at log.c line 429, log_info->log_configured = 0. >> >> Obviously, there ought to be a way in which I can force this to >> become true, but I don't see a way to do so. > > To be clear, currently "log.mgk" is intended to be searched for and > loaded in all cases except for MethodOutput where a call-back function > is used. > > I do see that InitializeLogInfoPost() was not observing the above > description when UseInstalledMagick is not defined, so I will submit a > fix for that. > > There is not currently a way to request that a log.mgk not be loaded > and to use only the default values. As I understand things now, it seems you are saying the if I set up a call back, I can send the info to any log target I chose to implement the code for. That then seems to imply that I should not need anything but to set the call back; any other log.mgk would be ignored and I really would not need the dummy calls to Initialize & DestroyMagick at all? If I could/can also set up the log events and format, I suppose that would work. Still, if that is needed to setup the static log data struct, a lot of work is done just for that. > >> I have renamed the log.mgk in my configuration directory as well as >> a copy in the executable directory. >> >> After this, the file path & name stayed put as defined by my app, but >> of course I could not reset the output to go to my file. > > Provided that a log.mgk is not loaded, I don't see why you can not > send the output to the file you specified. > > I will need to develop a Magick++ test program for this feature. I see > you still using the MagickLib namespace where I did not intend that it > should be required. If you need to use MagickLib in Magick++ code, > then there is a bug. Using the MagickLib qualifier was just part of my eater-egging to try and move ahead :-( My Hg workflow still needs refining. I clone the GM repos and then work in it; that seems to make it impossible to later update or pull from the main repo. Would I have to clone the main repo and then clone a second copy for me to work in? or is the simplest way to start over with a new cloned work dir? Arnold |
From: Bob F. <bfr...@si...> - 2020-03-25 13:54:06
|
On Tue, 24 Mar 2020, 10bxjfhf wrote: > > During the last call, at some point the log file name gets set to my > specified path: > > "C:\\Users\\arnold\\AppData\\Roaming\\wxIC-MT\\NewLogFile.log" > > at log.c line 354 from log_info_defaults.filename > > but after that, at log.c 434++ it is reset because some log.mgk is loaded > because at log.c line 429, log_info->log_configured = 0. > > Obviously, there ought to be a way in which I can force this to become true, > but I don't see a way to do so. To be clear, currently "log.mgk" is intended to be searched for and loaded in all cases except for MethodOutput where a call-back function is used. I do see that InitializeLogInfoPost() was not observing the above description when UseInstalledMagick is not defined, so I will submit a fix for that. There is not currently a way to request that a log.mgk not be loaded and to use only the default values. > I have renamed the log.mgk in my configuration directory as well as a copy > in the executable directory. > > After this, the file path & name stayed put as defined by my app, but of > course I could not reset the output to go to my file. Provided that a log.mgk is not loaded, I don't see why you can not send the output to the file you specified. I will need to develop a Magick++ test program for this feature. I see you still using the MagickLib namespace where I did not intend that it should be required. If you need to use MagickLib in Magick++ code, then there is a bug. Bob -- Bob Friesenhahn bfr...@si..., http://www.simplesystems.org/users/bfriesen/ GraphicsMagick Maintainer, http://www.GraphicsMagick.org/ Public Key, http://www.simplesystems.org/users/bfriesen/public-key.txt |
From: 10bxjfhf <10b...@te...> - 2020-03-25 02:03:42
|
What I have right now in my app's initialization: // new since Mar 24/20 InitializeMagick(NULL); MagickLib::DestroyMagick(); wxString wsT1; // path to the configuration files wxGetEnv( _T("MAGICK_CONFIGURE_PATH"), &wsT1 ); wxSetEnv( _T("MAGICK_CONFIGURE_PATH"), m_wsConfigDir ); wxGetEnv( _T("MAGICK_CONFIGURE_PATH"), &wsT1 ); // path to DLLs wxGetEnv( _T("MAGICK_HOME"), &wsT1 ); wsT1 = static_cast<const char*>( wsExePath); wxSetEnv( _T("MAGICK_HOME"), wsT1 ); wxGetEnv( _T("MAGICK_HOME"), &wsT1 ); // setting the file name & path before initializing does not // produce any errors, but also has no effect wxFileName wfnLogFile; wfnLogFile.SetPath(m_wsConfigDir); wfnLogFile.SetName( _T("NewLogFile.log") ); wxString wsLogFileName = wfnLogFile.GetFullPath(); std::string sLogFile = wsLogFileName.ToStdString( ); SetLogDefaultFileName( sLogFile ); // SetLogDefaultOutputType( MagickLib::TXTFileOutput ); InitializeMagick( static_cast<const char*>( wsExePath) ); During the last call, at some point the log file name gets set to my specified path: "C:\\Users\\arnold\\AppData\\Roaming\\wxIC-MT\\NewLogFile.log" at log.c line 354 from log_info_defaults.filename but after that, at log.c 434++ it is reset because some log.mgk is loaded because at log.c line 429, log_info->log_configured = 0. Obviously, there ought to be a way in which I can force this to become true, but I don't see a way to do so. I have renamed the log.mgk in my configuration directory as well as a copy in the executable directory. After this, the file path & name stayed put as defined by my app, but of course I could not reset the output to go to my file. Arnold |
From: 10bxjfhf <10b...@te...> - 2020-03-24 23:57:50
|
On 2020-03-24 2:47 p.m., Bob Friesenhahn wrote: > On Tue, 24 Mar 2020, 10bxjfhf wrote: >>> >>> Remember that the new SetLogDefault APIs are writing into a static >>> storage location so they will not be influenced by >>> InitializeMagick(). When InitializeMagick() is called, logging is >>> initialized and the static default values should be used. The static >>> default values are only used during initialization. >> >> OK, I have traced through the code and the default log file name and >> path can be set and it persists until some logevent is triggered, at >> which time it reverts back to the default from log.mgk. >> >> I have not been able to find where or how the change back is triggered. > > I don't see how that can be unless DestroyMagick() is called, and then > InitializeMagickEx()/InitializeMagick(). That is the only logging > initialization path. > > Regardless, I do see that there is a 'log_configured' flag which was > only set if log.mgk was loaded. However, the log.mgk should only be > loaded during the InitializeMagickEx() function call, and it should > only do something once even if is called more than once. If it is > initializing more than once then that would be a serious problem. > > I will set the 'log_configured' flag as a form of good-housekeeping. I'll be able to do a few more test later today, I hope > >> As a trial I tried to use SetLogDefaultOutputType before the call to >> SetLogDefaultFileName, but I can't figure out how to specify the >> argument for that function for TXTFileOutput > > The argument accepted by SetLogDefaultFileName() should be the same as > supported by "log.mgk" and can be any arbitrary file path. > > The documentation also says: > > "Place a %d in the file name in order to support multiple log > generations." SetLogDefaultFileName I'm ok with, it is SetLogDefaultOutputType which I cannot seem to give the proper arg to Arnold |
From: Bob F. <bfr...@si...> - 2020-03-24 21:47:24
|
On Tue, 24 Mar 2020, 10bxjfhf wrote: >> >> Remember that the new SetLogDefault APIs are writing into a static storage >> location so they will not be influenced by InitializeMagick(). When >> InitializeMagick() is called, logging is initialized and the static default >> values should be used. The static default values are only used during >> initialization. > > OK, I have traced through the code and the default log file name and path can > be set and it persists until some logevent is triggered, at which time it > reverts back to the default from log.mgk. > > I have not been able to find where or how the change back is triggered. I don't see how that can be unless DestroyMagick() is called, and then InitializeMagickEx()/InitializeMagick(). That is the only logging initialization path. Regardless, I do see that there is a 'log_configured' flag which was only set if log.mgk was loaded. However, the log.mgk should only be loaded during the InitializeMagickEx() function call, and it should only do something once even if is called more than once. If it is initializing more than once then that would be a serious problem. I will set the 'log_configured' flag as a form of good-housekeeping. > As a trial I tried to use SetLogDefaultOutputType before the call to > SetLogDefaultFileName, but I can't figure out how to specify the argument for > that function for TXTFileOutput The argument accepted by SetLogDefaultFileName() should be the same as supported by "log.mgk" and can be any arbitrary file path. The documentation also says: "Place a %d in the file name in order to support multiple log generations." Bob -- Bob Friesenhahn bfr...@si..., http://www.simplesystems.org/users/bfriesen/ GraphicsMagick Maintainer, http://www.GraphicsMagick.org/ Public Key, http://www.simplesystems.org/users/bfriesen/public-key.txt |
From: 10bxjfhf <10b...@te...> - 2020-03-24 21:06:40
|
On 2020-03-24 12:46 p.m., Bob Friesenhahn wrote: > On Tue, 24 Mar 2020, 10bxjfhf wrote: >> >> and MAGICK_HOME => to the executable directory with all of the DLLs >> etc, then I call again: >> >> InitializeMagick( static_cast<const char*>( wsExePath) ); >> >> and I again trace the log events. >> >> 8 go to stderr and the next 10 or so go to the text log file. >> >> Since I did not specify a path they end up in the parent of my debug >> directory - by now I know where to look :-) >> >> After this I try to set the new log file & path, but it does nothing >> and won't do anything until a new log file needs to be created >> because just assigning a new name & path does not close the current >> file. >> >> Trying to set the log file path & name before the second call to >> InitializeMagick() does not cause any errors but also does nothing >> because the default is reset when Initialize.. gets called the second >> time. > > Remember that the new SetLogDefault APIs are writing into a static > storage location so they will not be influenced by InitializeMagick(). > When InitializeMagick() is called, logging is initialized and the > static default values should be used. The static default values are > only used during initialization. OK, I have traced through the code and the default log file name and path can be set and it persists until some logevent is triggered, at which time it reverts back to the default from log.mgk. I have not been able to find where or how the change back is triggered. As a trial I tried to use SetLogDefaultOutputType before the call to SetLogDefaultFileName, but I can't figure out how to specify the argument for that function for TXTFileOutput Arnold |
From: Bob F. <bfr...@si...> - 2020-03-24 19:46:33
|
On Tue, 24 Mar 2020, 10bxjfhf wrote: > > and MAGICK_HOME => to the executable directory with all of the DLLs etc, then > I call again: > > InitializeMagick( static_cast<const char*>( wsExePath) ); > > and I again trace the log events. > > 8 go to stderr and the next 10 or so go to the text log file. > > Since I did not specify a path they end up in the parent of my debug > directory - by now I know where to look :-) > > After this I try to set the new log file & path, but it does nothing and > won't do anything until a new log file needs to be created because just > assigning a new name & path does not close the current file. > > Trying to set the log file path & name before the second call to > InitializeMagick() does not cause any errors but also does nothing because > the default is reset when Initialize.. gets called the second time. Remember that the new SetLogDefault APIs are writing into a static storage location so they will not be influenced by InitializeMagick(). When InitializeMagick() is called, logging is initialized and the static default values should be used. The static default values are only used during initialization. > Still not familiar enough with Hg to be able to just update via a 'pull' - > being a non-command-line guy I am using TortoiseHg but it look quite > different from TortoiseGit :-( Normally one does a "synchronize", also known as "pull" (which updates the repository itself) followed by an "update", which attempts to update the working files with changes. If you are lucky you will not need to do a merge. TortoiseHG provides the option to automatically update when doing the "synchronize". Bob -- Bob Friesenhahn bfr...@si..., http://www.simplesystems.org/users/bfriesen/ GraphicsMagick Maintainer, http://www.GraphicsMagick.org/ Public Key, http://www.simplesystems.org/users/bfriesen/public-key.txt |
From: 10bxjfhf <10b...@te...> - 2020-03-24 19:31:52
|
On 2020-03-23 12:32 p.m., Bob Friesenhahn wrote: > On Sun, 22 Mar 2020, 10bxjfhf wrote: >>> >>> I have not yet re-implemented the logging formatting code such that >>> the format set by the user is used for all cases. Currently the >>> user-specified > > I have now implemented consistent logging formatting code which obeys > the user. Good. Thank you. >> I am wondering about the different usages of std::string and >> std::wstring. For wxWidgets, everything is/needs to be converted to >> wide strings and when calling the underlying Win API functions, I >> typically need to ensure to pass wide strings. Is this handled by GM >> * Magick++ > > Magick++ and GraphicsMagick (being very old software started in > perhaps 1990) do not support wide strings. The only way things work > is if 7 or 8 bit string data is expressed in the same code-page as the > filesystem, or if Unicode is represented in UTF-8, which then needs to > be supported as such by the filesystem. There is an existing problem > report that GraphicsMagick on Windows is not able to open some UTF-8 > filenames containing Chinese characters. Different operating systems > have different capabilities and behavior when it comes to file names. > > Even wide-character support does not assure correct support for > internationalization because there is no assurance that there is not a > mis-match. ANSI C introduced wide characters in 1989 before standards > had evolved for how internationalization should be done. > This wide char support is still full of unexplored corners for myself, so I will have to put all that into my pipe & smoke it ;-) >> For Windows app with GM code linked as DLLs, all of the >> initialization is done when the OS first decides it needs the >> CORE_xx_magick_.dll > > Remember, this is configurable. Given the problems that it is > apparently causing, ProvideDllMain is no longer the default. Good; now I don't have to manually edit the configuration before generating the .sln file > > In the mean time, this sequence should work: > > InitializeMagick(NULL); > DestroyMagick(); > [ Do some defaults configuration ] This would only include the environment variables to be used by this instance. > If you put the .mgk files in the same directory as the DLL, they > should be found. For a static build, it would be best to put the .mgk > files in the same directory as the program. Unix-type systems work > much differently. For now, I have moved all of the *.mgk file to my configuration directory and am pointingMAGICK_CONFIGURE_PATH to that path. For InitializeMagick( static_cast<const char*>( wsExePath) ); I point it to the current executable; for now I have only worked with the debug DLLs; eventually I probably will try other configurations > >> I am considering linking the libs statically, though I am unsure >> whether it will help. I would expect the OS to still get its turn >> before me and the only way I see is to force a reload of the >> libraries or the DLLs at a point of my choosing. > > In this case there would be no DLL initialization so the OS would not > get its turn. You would be totally in control, but your program would > appear much larger. And I expect I would have to do much the same work to set things up :-) > >> FWIW, from here it looks as though the call to InitializeMagick from >> within the app needs to override all data for the specific function >> the call is expected to affect. At present, this does not happen for >> at least SetLogDefaultFileName() > > See my text above. Most of my time was spent on trying to understand what goes on behind the scenes, because it does not work, at least not the way I understand it. Fortunately I did remember a few lessons learned last time - and eventually I got some insight from pushing the log info to the IDE log output window. Once I located the place where the logging is done, tracing through the code showed some interesting things. When the app starts up, between InitializeMagick(NULL); MagickLib::DestroyMagick(); the first 8 or 9 log events are directed at stderr and the next 10 or so are directed at Win32EventLog After this I set MAGICK_CONFIGURE_PATH => my confi directory with all of the *.mgk files with log.mgk => <magicklog> <log events="blob" /> <log events="coder" /> <log events="configure" /> <log events="exception" /> <log events="Warning" /> <log events="Error" /> <log events="FatalError" /> <log output="txtfile" /> <!-- <log output="win32debug" /> --> <log filename="NMagick-%d.log" /> <log generations="3" /> <log limit="2000" /> <log format="%t %r %u %p %m/%f/%l/%d/%s:\n %e" /> </magicklog> and MAGICK_HOME => to the executable directory with all of the DLLs etc, then I call again: InitializeMagick( static_cast<const char*>( wsExePath) ); and I again trace the log events. 8 go to stderr and the next 10 or so go to the text log file. Since I did not specify a path they end up in the parent of my debug directory - by now I know where to look :-) After this I try to set the new log file & path, but it does nothing and won't do anything until a new log file needs to be created because just assigning a new name & path does not close the current file. Trying to set the log file path & name before the second call to InitializeMagick() does not cause any errors but also does nothing because the default is reset when Initialize.. gets called the second time. Again, any issues encountered before this file can be set are lost and unreported, hence very hard to track down - such as issues with the log.mgk, which seems to be the only file accessed at this stage. Also, at this time I have not yet taken the time to see what the messages directed to stderr refer to, because I wanted to get out this feedback ASAP. Eventually I will try to do so. > > Please pull the latest changes and see if you are more satisfied. Still not familiar enough with Hg to be able to just update via a 'pull' - being a non-command-line guy I am using TortoiseHg but it look quite different from TortoiseGit :-( Another leaning curve ;-) Arnold |
From: Bob F. <bfr...@si...> - 2020-03-23 19:32:32
|
On Sun, 22 Mar 2020, 10bxjfhf wrote: >> >> I have not yet re-implemented the logging formatting code such that the >> format set by the user is used for all cases. Currently the user-specified I have now implemented consistent logging formatting code which obeys the user. > I have played with it a bit and compiled the latest libraries. Preliminary > comments: > > SetLogDefaultFileName( swLogFile ); > > IMO would be useful to return the current log file string for display in > About as feedback > also would allow splitting out some specific log info for a section of > code/function and restoring the default at a later time. That seems useful. For other areas, the command-line supports the -list option which prints out a summary to a file descriptor. This is not the same as accessor functions but it seems like the logging configuration should be included as a supported option. > I am wondering about the different usages of std::string and std::wstring. > For wxWidgets, everything is/needs to be converted to wide strings and when > calling the underlying Win API functions, I typically need to ensure to pass > wide strings. Is this handled by GM * Magick++ Magick++ and GraphicsMagick (being very old software started in perhaps 1990) do not support wide strings. The only way things work is if 7 or 8 bit string data is expressed in the same code-page as the filesystem, or if Unicode is represented in UTF-8, which then needs to be supported as such by the filesystem. There is an existing problem report that GraphicsMagick on Windows is not able to open some UTF-8 filenames containing Chinese characters. Different operating systems have different capabilities and behavior when it comes to file names. Even wide-character support does not assure correct support for internationalization because there is no assurance that there is not a mis-match. ANSI C introduced wide characters in 1989 before standards had evolved for how internationalization should be done. > > This initially came up with: > > wxString wsLogFileName = wfnLogFile.GetFullPath(); > std::string sLogFile = wsLogFileName.ToStdString( ); > SetLogDefaultFileName( sLogFile ); > > So far I have not been able to set my own file name & path from within the > app. > > 2 things seems to get in the way and I have not been able to untangle all of > the interconnected issues. > > For Windows app with GM code linked as DLLs, all of the initialization is > done when the OS first decides it needs the CORE_xx_magick_.dll Remember, this is configurable. Given the problems that it is apparently causing, ProvideDllMain is no longer the default. In the mean time, this sequence should work: InitializeMagick(NULL); DestroyMagick(); [ Do some defaults configuration ] InitializeMagick(NULL); > MAGICK_CONFIGURE_PATH seems to have to be undefined or blank, but undefining > or keeping MAGICK_HOME blank causes issues because delegates.mgk is not > found. If you put the .mgk files in the same directory as the DLL, they should be found. For a static build, it would be best to put the .mgk files in the same directory as the program. Unix-type systems work much differently. > I am considering linking the libs statically, though I am unsure whether it > will help. I would expect the OS to still get its turn before me and the only > way I see is to force a reload of the libraries or the DLLs at a point of my > choosing. In this case there would be no DLL initialization so the OS would not get its turn. You would be totally in control, but your program would appear much larger. > FWIW, from here it looks as though the call to InitializeMagick from within > the app needs to override all data for the specific function the call is > expected to affect. At present, this does not happen for at least > SetLogDefaultFileName() See my text above. Please pull the latest changes and see if you are more satisfied. Bob -- Bob Friesenhahn bfr...@si..., http://www.simplesystems.org/users/bfriesen/ GraphicsMagick Maintainer, http://www.GraphicsMagick.org/ Public Key, http://www.simplesystems.org/users/bfriesen/public-key.txt |
From: 10bxjfhf <10b...@te...> - 2020-03-23 02:27:56
|
Thank you for working on this project. On 2020-03-22 11:29 a.m., Bob Friesenhahn wrote: > I have just pushed a Mercurial changeset which adds a bunch of C and > C++ functions for setting logger defaults as well as a C-style > callback. See the ChangeLog file for details. > > The C API documentation can be found at > > http://www.graphicsmagick.org/api/log.html > > and the C++ API documentation can be found at > > http://www.graphicsmagick.org/Magick++/Image.html#explicit-logging-configuration-and-callbacks > > I have not yet re-implemented the logging formatting code such that > the format set by the user is used for all cases. Currently the > user-specified format is used for cases which write to a file handle > (file, stderr, stdout). A user-specified formatter does not make > sense for the XML file output since it provides discrete parameters. > > Please test and make me aware of any problems. I have played with it a bit and compiled the latest libraries. Preliminary comments: SetLogDefaultFileName( swLogFile ); IMO would be useful to return the current log file string for display in About as feedback also would allow splitting out some specific log info for a section of code/function and restoring the default at a later time. I am wondering about the different usages of std::string and std::wstring. For wxWidgets, everything is/needs to be converted to wide strings and when calling the underlying Win API functions, I typically need to ensure to pass wide strings. Is this handled by GM * Magick++ This initially came up with: wxString wsLogFileName = wfnLogFile.GetFullPath(); std::string sLogFile = wsLogFileName.ToStdString( ); SetLogDefaultFileName( sLogFile ); So far I have not been able to set my own file name & path from within the app. 2 things seems to get in the way and I have not been able to untangle all of the interconnected issues. For Windows app with GM code linked as DLLs, all of the initialization is done when the OS first decides it needs the CORE_xx_magick_.dll MAGICK_CONFIGURE_PATH seems to have to be undefined or blank, but undefining or keeping MAGICK_HOME blank causes issues because delegates.mgk is not found. I am considering linking the libs statically, though I am unsure whether it will help. I would expect the OS to still get its turn before me and the only way I see is to force a reload of the libraries or the DLLs at a point of my choosing. Not a very attractive option. FWIW, from here it looks as though the call to InitializeMagick from within the app needs to override all data for the specific function the call is expected to affect. At present, this does not happen for at least SetLogDefaultFileName() I have not had had a chance to track down where the file name is actually used for output and will give it a try over the next couple of days, to sort out a bit more of this puzzle. > Given the current viral outbreak, I am very aware of my own mortality > and I want to make sure that GraphicsMagick is in the best shape and > has a chance to independently survive in the future if something > happens to me. Understood all too well. Things are also heating up around here. Arnold |
From: Bob F. <bfr...@si...> - 2020-03-22 18:29:19
|
I have just pushed a Mercurial changeset which adds a bunch of C and C++ functions for setting logger defaults as well as a C-style callback. See the ChangeLog file for details. The C API documentation can be found at http://www.graphicsmagick.org/api/log.html and the C++ API documentation can be found at http://www.graphicsmagick.org/Magick++/Image.html#explicit-logging-configuration-and-callbacks I have not yet re-implemented the logging formatting code such that the format set by the user is used for all cases. Currently the user-specified format is used for cases which write to a file handle (file, stderr, stdout). A user-specified formatter does not make sense for the XML file output since it provides discrete parameters. Please test and make me aware of any problems. Given the current viral outbreak, I am very aware of my own mortality and I want to make sure that GraphicsMagick is in the best shape and has a chance to independently survive in the future if something happens to me. Bob -- Bob Friesenhahn bfr...@si..., http://www.simplesystems.org/users/bfriesen/ GraphicsMagick Maintainer, http://www.GraphicsMagick.org/ Public Key, http://www.simplesystems.org/users/bfriesen/public-key.txt |
From: 10bxjfhf <10b...@te...> - 2020-03-20 17:52:16
|
On 2020-03-20 10:16 a.m., Bob Friesenhahn wrote: > On Fri, 20 Mar 2020, 10bxjfhf wrote: >>> >>> It may be that the application just wants access to parameterized >>> raw data, or it may be that the application wants to receive a >>> formatted string based on the specified log format. >> >> For logging, it would be nice to be able to specify the format and >> possibly a severity flag to simplify the amount of data coming back & >> time spent handling it. > > Some other users might want the original data provided in order to > make decisions on it, or to format it using their own code. I see no problem with giving them that option. Arnold |
From: Bob F. <bfr...@si...> - 2020-03-20 17:16:29
|
On Fri, 20 Mar 2020, 10bxjfhf wrote: >> >> It may be that the application just wants access to parameterized raw data, >> or it may be that the application wants to receive a formatted string based >> on the specified log format. > > For logging, it would be nice to be able to specify the format and possibly a > severity flag to simplify the amount of data coming back & time spent > handling it. Some other users might want the original data provided in order to make decisions on it, or to format it using their own code. Bob -- Bob Friesenhahn bfr...@si..., http://www.simplesystems.org/users/bfriesen/ GraphicsMagick Maintainer, http://www.GraphicsMagick.org/ Public Key, http://www.simplesystems.org/users/bfriesen/public-key.txt |
From: 10bxjfhf <10b...@te...> - 2020-03-20 15:55:32
|
On 2020-03-20 6:18 a.m., Bob Friesenhahn wrote: > You may not have heard from me for a while (a week) but I have been > working to add the ability to configure logging and accept log reports > using only APIs so that log.mgk is not required. This has been coming > along well but I was not happy about adding a C-style callback > interface to Magick++ (and there were strange compilation issues > regarding it) so I have held off on commits. Anything I add to > Magick++ needs to be suitably generic and able to stand the test of time. Time is not a problem for me at this time. There is plenty to keep me busy ;-) > > I am thinking that a function-object style interface is most suitable > for the Magick++ logging callback implementation so that the > application can inherit from it and can implement whatever functions > it needs. Because you know the 'innards' of all this code way better than I, that I am happy to leave the implementation to you. > > It may be that the application just wants access to parameterized raw > data, or it may be that the application wants to receive a formatted > string based on the specified log format. For logging, it would be nice to be able to specify the format and possibly a severity flag to simplify the amount of data coming back & time spent handling it. Arnold |
From: Bob F. <bfr...@si...> - 2020-03-20 13:18:39
|
You may not have heard from me for a while (a week) but I have been working to add the ability to configure logging and accept log reports using only APIs so that log.mgk is not required. This has been coming along well but I was not happy about adding a C-style callback interface to Magick++ (and there were strange compilation issues regarding it) so I have held off on commits. Anything I add to Magick++ needs to be suitably generic and able to stand the test of time. I am thinking that a function-object style interface is most suitable for the Magick++ logging callback implementation so that the application can inherit from it and can implement whatever functions it needs. It may be that the application just wants access to parameterized raw data, or it may be that the application wants to receive a formatted string based on the specified log format. Bob -- Bob Friesenhahn bfr...@si..., http://www.simplesystems.org/users/bfriesen/ GraphicsMagick Maintainer, http://www.GraphicsMagick.org/ Public Key, http://www.simplesystems.org/users/bfriesen/public-key.txt |