Algorithms used in ImageMagick - c

I used Imagemagick in my project. I implemented a sub-image detection system using the compare command of ImageMagick. It is working well giving fine results. By reading articles i got to know that ImageMagick compares pixels of small image at every possible position within the pixels of larger image.And also i got to know ImageMagick detects rotated images and scaled images using Fuzzy factor.I was able to find the source code related to compare command.
const Image *reconstruct_image,double *distortion,ExceptionInfo *exception)
585 {
586 CacheView
587 *image_view,
588 *reconstruct_view;
589
590 double
591 area;
592
593 MagickBooleanType
594 status;
595
596 register ssize_t
597 j;
598
599 size_t
600 columns,
601 rows;
602
603 ssize_t
604 y;
605
606 status=MagickTrue;
607 rows=MagickMax(image->rows,reconstruct_image->rows);
608 columns=MagickMax(image->columns,reconstruct_image->columns);
609 area=0.0;
610 image_view=AcquireVirtualCacheView(image,exception);
611 reconstruct_view=AcquireVirtualCacheView(reconstruct_image,exception);
612 #if defined(MAGICKCORE_OPENMP_SUPPORT)
613 #pragma omp parallel for schedule(static,4) shared(status) \
614 magick_threads(image,image,rows,1) reduction(+:area)
615 #endif
616 for (y=0; y < (ssize_t) rows; y++)
617 {
618 double
619 channel_distortion[MaxPixelChannels+1];
620
621 register const Quantum
622 *magick_restrict p,
623 *magick_restrict q;
624
625 register ssize_t
626 x;
627
628 if (status == MagickFalse)
629 continue;
630 p=GetCacheViewVirtualPixels(image_view,0,y,columns,1,exception);
631 q=GetCacheViewVirtualPixels(reconstruct_view,0,y,columns,1,exception);
632 if ((p == (const Quantum *) NULL) || (q == (const Quantum *) NULL))
633 {
634 status=MagickFalse;
635 continue;
636 }
637 (void) ResetMagickMemory(channel_distortion,0,sizeof(channel_distortion));
638 for (x=0; x < (ssize_t) columns; x++)
639 {
640 double
641 Da,
642 Sa;
643
644 register ssize_t
645 i;
646
647 if ((GetPixelReadMask(image,p) == 0) ||
648 (GetPixelReadMask(reconstruct_image,q) == 0))
649 {
650 p+=GetPixelChannels(image);
651 q+=GetPixelChannels(reconstruct_image);
652 continue;
653 }
654 Sa=QuantumScale*GetPixelAlpha(image,p);
655 Da=QuantumScale*GetPixelAlpha(reconstruct_image,q);
656 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
657 {
658 double
659 distance;
660
661 PixelChannel channel=GetPixelChannelChannel(image,i);
662 PixelTrait traits=GetPixelChannelTraits(image,channel);
663 PixelTrait reconstruct_traits=GetPixelChannelTraits(reconstruct_image,
664 channel);
665 if ((traits == UndefinedPixelTrait) ||
666 (reconstruct_traits == UndefinedPixelTrait) ||
667 ((reconstruct_traits & UpdatePixelTrait) == 0))
668 continue;
669 distance=QuantumScale*fabs(Sa*p[i]-Da*GetPixelChannel(reconstruct_image,
670 channel,q));
671 channel_distortion[i]+=distance;
672 channel_distortion[CompositePixelChannel]+=distance;
673 }
674 area++;
675 p+=GetPixelChannels(image);
676 q+=GetPixelChannels(reconstruct_image);
677 }
678 #if defined(MAGICKCORE_OPENMP_SUPPORT)
679 #pragma omp critical (MagickCore_GetMeanAbsoluteError)
680 #endif
681 for (j=0; j <= MaxPixelChannels; j++)
682 distortion[j]+=channel_distortion[j];
683 }
684 reconstruct_view=DestroyCacheView(reconstruct_view);
685 image_view=DestroyCacheView(image_view);
686 area=PerceptibleReciprocal(area);
687 for (j=0; j <= MaxPixelChannels; j++)
688 distortion[j]*=area;
689 distortion[CompositePixelChannel]/=(double) GetImageChannels(image);
690 return(status);
691 }
Anyone have an idea about what are the conditions they are searching for in the following code snippet?
if ((traits == UndefinedPixelTrait) ||
666 (reconstruct_traits == UndefinedPixelTrait) ||
667 ((reconstruct_traits & UpdatePixelTrait) == 0))

In case you're wondering how these values are used:
http://www.learncpp.com/cpp-tutorial/3-8a-bit-flags-and-bit-masks/
Those values are nothing but different bits. They are different so you can combine them and check them in a disambiguous way.
In case you don't know the meaning of UndefinedPixelTraits and so on, just google the word and you'll end up in the ImageMagick documentation:
https://www.imagemagick.org/include/porting.php
Pixel Traits
Each pixel channel includes one or more of these traits:
Undefined no traits associated with this pixel channel Copy do not
update this pixel channel, just copy it Update update this pixel
channel Blend blend this pixel channel with the alpha mask if it's
enabled We provide these methods to set and get pixel traits:
GetPixelAlphaTraits() SetPixelAlphaTraits() GetPixelBlackTraits()
SetPixelBlackTraits() GetPixelBlueTraits() SetPixelBlueTraits()
GetPixelCbTraits() SetPixelCbTraits() GetPixelChannelTraits()
SetPixelChannelTraits() GetPixelCrTraits() SetPixelCrTraits()
GetPixelGrayTraits() SetPixelGrayTraits() GetPixelGreenTraits()
SetPixelGreenTraits() GetPixelIndexTraits() SetPixelIndexTraits()
GetPixelMagentaTraits() SetPixelMagentaTraits() GetPixelRedTraits()
SetPixelRedTraits() GetPixelYellowTraits() SetPixelYellowTraits()
GetPixelYTraits() SetPixelYTraits() For convenience you can set
the active trait for a set of pixel channels with a channel mask and
this method:
SetImageChannelMask() Previously MagickCore methods had channel
analogs, for example, NegateImage() and NegateImageChannels(). The
channel analog methods are no longer necessary because the pixel
channel traits specify whether to act on a particular pixel channel or
whether to blend with the alpha mask. For example, instead of
NegateImageChannel(image,channel); we use:
channel_mask=SetImageChannelMask(image,channel);
NegateImage(image,exception); (void)
SetImageChannelMask(image,channel_mask);
If you want to know how and why each method is handling those flags read the respective documentation or the code itself.

Related

Erreur de segmentation (core dumped) when trying to read txt file in C

I want to read a pgm file in C language using fgets but i get an error and i don't know which instruction cause it.
Here is my code :
FILE* file = NULL;
char chaine[TAILLE_MAX] = "";
int elts[TAILLE_MAX];
image = fopen("test.txt", "r+");
if(image != NULL)
{
int i=0;
while (fgets(chaine, TAILLE_MAX, file) != NULL)
{
elts[i] = atoi(chaine);
printf("%d\n", i);
i++;
}
}
It reads until the last line of the file. Here is the output :
...
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
RUN FINISHED; Segmentation fault; core dumped; real time: 140ms; user: 0ms; system: 0ms
The probleme is not the file but i think it's about the fgets function
The text-based PGM files will contain many values on each line for the pixels. With pixels[i] = atoi(chaine) you only convert the first of those numbers.
You need to parse or tokenize the lines to get all the pixels.
And of course, you need to make sure that the values you read can fit in the destination integer array, which needs to be W * H elements large (where W is the image width and H is the image height).
And as with all image formats, even text-based such, I really recommend you find a library to handle it for you.

Reading a File in C isn't working?

so I tried looking around and I couldn't find an answer. I'm trying to read from a file I write in a different program. Writing it works fine, but when I try and read it, there is no output at all. Here's the code.
struct data{
int tp, gpm, deg;
};
int main()
{
struct data list[21];
int p[21];
list[0].tp = 10;
FILE * fout;
fopen("data_list", "r");
for(int i = 0; i < 21; i++){
fscanf(fopen, "%d:\t%d\t%d\t%d\n", &p[i], &list[i].tp, &list[i].gpm, &list[i].deg);
}
for(int i = 0; i < 21; i++){
printf("%d:\t%d\t%d\t%d\n", p[i], list[i].tp, list[i].gpm, list[i].deg);
}
fclose(fout);
return 0;
}
Here's the file I'm trying to read
-10:651 17 108
-9: 514 16 142
-8: 588 16 169
-7: 542 10 160
-6: 531 17 127
-5: 688 15 158
-4: 619 18 122
-3: 658 14 170
-2: 588 11 182
-1: 541 12 139
+0: 641 19 114
+1: 668 17 200
+2: 517 19 157
+3: 589 13 121
+4: 696 13 140
+5: 526 12 157
+6: 630 12 137
+7: 685 11 105
+8: 556 11 120
+9: 645 15 188
+10:624 19 185
Can anyone help me out? I've only been learning C for a couple months, most of it selftaught
fscanf(fopen, "%d:\t%d\t%d\t%d\n"
I have no idea how that possibly even compiled, but you are passing a function pointer where a FILE* is required. That definitely will not work correctly.
The correct thing to pass there is the return value from your fopen() call (which at the moment you've been discarding).

Write a C program that reads in the integers from the accompanying data file and use insertion sort to store the sorted data into an array

Write a C program that implements a simple array-based insertion sort.
Your program must read in the integers from the accompanying data file
and use insertion sort to store the sorted data into an array. If you
must insert an element between two existing values, then you must also
move (or shift) the elements all elements with an index >= the index
where you wish to insert the new element. Note that you can find the
insertion sort algorithm in the textbook and the slides.
This is the ints from the text file. The ints are under each other and not the way they are shown here:
879
646
80
385
741
57
370
240
111
400
262
678
951
506
720
508
792
863
677
864
70
5
591
440
989
478
867
636
278
827
692
243
806
676
158
550
425
226
783
129
876
714
125
721
164
555
730
146
596
947
174
837
48
589
808
868
694
677
379
62
580
165
956
139
215
14
45
552
98
154
702
661
997
825
363
782
229
915
281
397
295
219
231
476
253
22
873
504
653
698
772
184
453
508
977
863
624
947
104
926
This the code I have for now. I am getting the addresses in order but now the integers from the file. When i comment out the insertionSort function, the numbers print fine but obviously not in order. What am i doing wrong?
#include <stdio.h>
#include<stdio.h>
void insertionSort(int *, int);
int main()
{
int i,num,array[1000];
FILE *fp = fopen("data_a5.txt","r");
fscanf(fp,"%d",&num);
if(fp== NULL)
{
printf("Error reading File!\n");
return;
}
while(!feof(fp))
{
fscanf(fp,"%d", &array[num]);
//printf("%d\n", array[num]);
}
insertionSort(array,num);
for(i=0;i<num;i++)
printf("%d\n",&array[i]);
fclose(fp);
return 0;
}
void insertionSort(int *value, int size)
{
int i,j,temp;
for(i = 0; i <= size; i++)
{
for(j = i; j >= 0; j--)
{
if(value[j+1]<value[j])
{
temp=value[j+1];
value[j+1]=value[j];
value[j]=temp;
}
else
break;
}
}
}
If your task is to have your array sorted as items are inserted (ie. "live") you best bet is to use linked structures.
For example:
struct myinst
{
int mynum;
struct myinst *prev;
struct myinst *next;
};
There a lot of examples, here is one: http://www.tutorialspoint.com/data_structures_algorithms/linked_list_program_in_c.htm
When you insert a new item to have your array/linked list sorted you go through your linked list and find the item that is nearest to the new one and then perform an insert by creating new memory an change prev/next addresses in existing items so that they point to the new item.

C sscanf (fscanf) behaving differently row from row

I've this snippet of code which should read text from input file and put it in a struct.
void load(FILE *fin, struct camion payload[]){
int i=0;
char except;
char buf[1000];
while (fgets(buf,sizeof(buf),fin)){
except='A';
sscanf(buf,"%i-%i-%i %i %s %c",&payload[i].day,&payload[i]. month,&payload[i].year,&payload[i].nparcels,payload[i].origin,&except);
if (except=='E')
payload[i].except=1;
i++;
}
}
The fgets works as it should (tested it), but the fscanf starting with this file:
01-01-2013 354 hub_J
01-01-2013 109 hub_L
03-01-2013 129 hub_J
04-01-2013 265 hub_J
08-01-2013 488 hub_B
09-01-2013 127 hub_J
09-01-2013 136 hub_K
09-01-2013 97 hub_D
10-01-2013 369 hub_O
11-01-2013 455 hub_G
12-01-2013 125 hub_I E
13-01-2013 105 hub_O
13-01-2013 468 hub_C
13-01-2013 360 hub_H E
returns (the printing function is not the problem, the problem happens right when the sscanf is executed) this:
1- 1-2013 354 hub_J
1- 1-2013 109 hub_L
3- 1-2013 129 hub_J
4- 1-2013 265 hub_J
0- 0- 0 0
0- 0- 0 0
0- 0- 0 0
0- 0- 0 0
10- 1-2013 369 hub_O
11- 1-2013 455 hub_G
12- 1-2013 125 hub_I E
13- 1-2013 105 hub_O
13- 1-2013 468 hub_C
13- 1-2013 360 hub_H E
The rows with E mean oversize payload, thus E is not always present, but this shouldn't be the error.
I'm banging my head against the wall.
thanks in advance
Scanning with %i and values with a leading zero are assumed to be octal. 08 and 09 are not octal values. Use %d instead as leading zero's are ignored and values are in base 10.
For the sscanf you might try this. It will scan the five items present in all the lines. The %n specifier will give you the characters processed by the scan. You can then test buf[offset]. If a newline is there, then the entire string was processed. Otherwise there is more to the string and a second sscanf can capture the remaining character.
Disclaimer: I have not compiled and tested this code.
void load(FILE *fin, struct camion payload[]){
int i=0;
int offset=0;
char except;
char buf[1000];
while (fgets(buf,sizeof(buf),fin)){
except='A';
if ( ( sscanf(buf,"%d-%d-%d %d %s%n"
,&payload[i].day
,&payload[i].month
,&payload[i].year
,&payload[i].nparcels
,payload[i].origin
,&offset)) == 5) {
if ( buf[offset] != '\n') {
sscanf(buf+offset, " %c", &except);
}
}
if (except=='E') {
payload[i].except=1;
}
i++;
}
}

In the Linux kernel, what does it mean for a process to be "whole"?

This code is from the file /fs/proc/array.c in the Linux headers. What does the int whole parameter mean? I want to know why sometimes you need to accumulate min_flt and maj_flts from the sig_struct and other times it's ok to just read their values straight out of the task_struct
346 static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
347 struct pid *pid, struct task_struct *task, int whole)
...
406 /* add up live thread stats at the group level */
407 if (whole) {
408 struct task_struct *t = task;
409 do {
410 min_flt += t->min_flt;
411 maj_flt += t->maj_flt;
412 gtime = cputime_add(gtime, t->gtime);
413 t = next_thread(t);
414 } while (t != task);
415
416 min_flt += sig->min_flt;
417 maj_flt += sig->maj_flt;
418 thread_group_times(task, &utime, &stime);
419 gtime = cputime_add(gtime, sig->gtime);
420 }
...
431 if (!whole) {
432 min_flt = task->min_flt;
433 maj_flt = task->maj_flt;
434 task_times(task, &utime, &stime);
435 gtime = task->gtime;
436 }
"whole" is just an argument name and in this context it seems to indicate "do_task_stat for the whole thread group".
do_task_stat is a static function only used within /fs/proc/array.c It is used in two places: proc_tid_stat (TID is "thread ID") and proc_tgid_stat (TGID is "thread group ID").
See Linux - Threads and Process for good explaination of thread groups.

Resources