WeixiangYan/CodeTransOcean huggingface dataset:
Task: Bitmap_Bézier curves_Quadratic

C: void quad_bezier(
        image img,
        unsigned int x1, unsigned int y1,
        unsigned int x2, unsigned int y2,
        unsigned int x3, unsigned int y3,
        color_component r,
        color_component g,
        color_component b );










Fortran: subroutine quad_bezier(img, p1, p2, p3, color)
  type(rgbimage), intent(inout) :: img
  type(point), intent(in) :: p1, p2, p3
  type(rgb), intent(in) :: color

  integer :: i, j
  real :: pts(0:N_SEG,0:1), t, a, b, c, x, y

  do i = 0, N_SEG
     t = real(i) / real(N_SEG)
     a = (1.0 - t)**2.0
     b = 2.0 * t * (1.0 - t)
     c = t**2.0
     x = a * p1%x + b * p2%x + c * p3%x 
     y = a * p1%y + b * p2%y + c * p3%y 
     pts(i,0) = x
     pts(i,1) = y
  end do

  do i = 0, N_SEG-1
     j = i + 1
     call draw_line(img, point(pts(i,0), pts(i,1)), &
                    point(pts(j,0), pts(j,1)), color)
  end do

end subroutine quad_bezier
Task: Verify distribution uniformity_Chi-squared test

C: #include <stdlib.h>
#include <stdio.h>
#include <math.h>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif

typedef double (* Ifctn)( double t);

double Simpson3_8( Ifctn f, double a, double b, int N)
{
    int j;
    double l1;
    double h = (b-a)/N;
    double h1 = h/3.0;
    double sum = f(a) + f(b);

    for (j=3*N-1; j>0; j--) {
        l1 = (j%3)? 3.0 : 2.0;
        sum += l1*f(a+h1*j) ;
    }
    return h*sum/8.0;
}

#define A 12
double Gamma_Spouge( double z )
{
    int k;
    static double cspace[A];
    static double *coefs = NULL;
    double accum;
    double a = A;

    if (!coefs) {
        double k1_factrl = 1.0;
        coefs = cspace;
        coefs[0] = sqrt(2.0*M_PI);
        for(k=1; k<A; k++) {
            coefs[k] = exp(a-k) * pow(a-k,k-0.5) / k1_factrl;
            k1_factrl *= -k;
        }
    }

    accum = coefs[0];
    for (k=1; k<A; k++) {
        accum += coefs[k]/(z+k);
    }
    accum *= exp(-(z+a)) * pow(z+a, z+0.5);
    return accum/z;
}

double aa1;
double f0( double t)
{
    return  pow(t, aa1)*exp(-t); 
}

double GammaIncomplete_Q( double a, double x)
{
    double y, h = 1.5e-2;  

    
    y = aa1 = a-1;
    while((f0(y) * (x-y) > 2.0e-8) && (y < x))   y += .4;
    if (y>x) y=x;

    return 1.0 - Simpson3_8( &f0, 0, y, (int)(y/h))/Gamma_Spouge(a);
}










Fortran: module gsl_mini_bind_m

    use iso_c_binding
    implicit none
    private

    public :: p_value

    interface
        function gsl_cdf_chisq_q(x, nu) bind(c, name='gsl_cdf_chisq_Q')
            import
            real(c_double), value :: x
            real(c_double), value :: nu
            real(c_double) :: gsl_cdf_chisq_q
        end function gsl_cdf_chisq_q
    end interface

contains

    
    real function p_value(x, df)
        real, intent(in) :: x
        integer, intent(in) :: df

        p_value = real(gsl_cdf_chisq_q(real(x, c_double), real(df, c_double)))

    end function p_value

end module gsl_mini_bind_m
Task: CSV to HTML translation

C: #include <stdio.h>

const char *input = 
	"Character,Speech\n"
	"The multitude,The messiah! Show us the messiah!\n"
	"Brians mother,<angry>Now you listen here! He's not the messiah; "
		"he's a very naughty boy! Now go away!</angry>\n"
	"The multitude,Who are you?\n"
	"Brians mother,I'm his mother; that's who!\n"
	"The multitude,Behold his mother! Behold his mother!";

int main()
{
	const char *s;
	printf("<table>\n<tr><td>");
	for (s = input; *s; s++) {
		switch(*s) {
		case '\n': printf("</td></tr>\n<tr><td>"); break;
		case ',':  printf("</td><td>"); break;
		case '<':  printf("&lt;"); break;
		case '>':  printf("&gt;"); break;
		case '&':  printf("&amp;"); break;
		default:   putchar(*s);
		}
	}
	puts("</td></tr>\n</table>");

	return 0;
}










Fortran:       SUBROUTINE CSVTEXT2HTML(FNAME,HEADED)	
Converts without checking field counts, or noting special characters.
       CHARACTER*(*) FNAME	
       LOGICAL HEADED		
       INTEGER MANY		
       PARAMETER (MANY=666)	
       CHARACTER*(MANY) ALINE	
       INTEGER MARK(0:MANY + 1)	
       INTEGER I,L,N		
       CHARACTER*2 WOT(2)	
       PARAMETER (WOT = (/"th","td"/))	
       INTEGER IT		
       INTEGER KBD,MSG,IN		
       COMMON /IOUNITS/ KBD,MSG,IN	
        OPEN(IN,FILE=FNAME,STATUS="OLD",ACTION="READ",ERR=661)	
        WRITE (MSG,1)			
    1   FORMAT ("<Table border=1>")	
        MARK(0) = 0		
        N = 0			

   10   READ (IN,11,END = 20) L,ALINE(1:MIN(L,MANY))	
   11   FORMAT (Q,A)		
        N = N + 1		
        IF (L.GT.MANY) THEN	
          WRITE (MSG,12) N,L,MANY	
   12     FORMAT ("Line ",I0," has length ",I0,"
          L = MANY			
        END IF			
        IF (N.EQ.1 .AND. HEADED) THEN	
          WRITE (MSG,*) "<tHead>"	
          IT = 1			
         ELSE				
          IT = 2			
        END IF			
        NCOLS = 0		
        DO I = 1,L		
          IF (ICHAR(ALINE(I:I)).EQ.ICHAR(",")) THEN	
            NCOLS = NCOLS + 1		
            MARK(NCOLS) = I		
          END IF			
        END DO			
        NCOLS = NCOLS + 1	
        MARK(NCOLS) = L + 1	
        WRITE (MSG,13)		
     1   (WOT(IT),				
     2    ALINE(MARK(I - 1) + 1:MARK(I) - 1),	
     3    WOT(IT),				
     4    I = 1,NCOLS),			
     5   "/tr"			
   13   FORMAT (" <tr>",666("<",A,">",A,"</",A,">"))	
        IF (N.EQ.1 .AND. HEADED) WRITE (MSG,*) "</tHead>"	
        GO TO 10		

   20   CLOSE (IN)		
        WRITE (MSG,21)		
   21   FORMAT ("</Table>")	
       RETURN			
Confusions.
  661   WRITE (MSG,*) "Can't open file ",FNAME	
      END			

      INTEGER KBD,MSG,IN
      COMMON /IOUNITS/ KBD,MSG,IN
      KBD = 5	
      MSG = 6	
      IN = 10	

      CALL CSVTEXT2HTML("Text.csv",.FALSE.)	
      WRITE (MSG,*)
      CALL CSVTEXT2HTML("Text.csv",.TRUE.)	
      END
Task: Pythagorean triples

C: #include <stdio.h>
#include <stdlib.h>
 
typedef unsigned long long xint;
typedef unsigned long ulong;

inline ulong gcd(ulong m, ulong n)
{
    ulong t;
    while (n) { t = n; n = m % n; m = t; }
    return m;
}
 
int main()
{
    ulong a, b, c, pytha = 0, prim = 0, max_p = 100;
    xint aa, bb, cc;

    for (a = 1; a <= max_p / 3; a++) {
        aa = (xint)a * a;
        printf("a = %lu\r", a); 
        fflush(stdout);

        
        for (b = a + 1; b < max_p/2; b++) {
            bb = (xint)b * b;
            for (c = b + 1; c < max_p/2; c++) {
                cc = (xint)c * c;
                if (aa + bb < cc) break;
                if (a + b + c > max_p) break;

                if (aa + bb == cc) {
                    pytha++;
                    if (gcd(a, b) == 1) prim++;
                }
            }
        }
    }
 
    printf("Up to %lu, there are %lu triples, of which %lu are primitive\n",
        max_p, pytha, prim);

    return 0;
}










Fortran: module triples
  implicit none
  
  integer :: max_peri, prim, total
  integer :: u(9,3) = reshape((/ 1, -2, 2,  2, -1, 2,  2, -2, 3, &
                                 1,  2, 2,  2,  1, 2,  2,  2, 3, &
                                -1,  2, 2, -2,  1, 2, -2,  2, 3 /), &
                                (/ 9, 3 /))
                                
contains

recursive subroutine new_tri(in)
  integer, intent(in) :: in(:)
  integer :: i
  integer :: t(3), p

  p = sum(in)
  if (p > max_peri) return

  prim = prim + 1
  total = total + max_peri / p
  do i = 1, 3
    t(1) = sum(u(1:3, i) * in)
    t(2) = sum(u(4:6, i) * in)
    t(3) = sum(u(7:9, i) * in)
    call new_tri(t);
  end do
end subroutine new_tri
end module triples

program Pythagorean
  use triples
  implicit none

  integer :: seed(3) = (/ 3, 4, 5 /)
  
  max_peri = 10
  do
    total = 0
    prim = 0
    call new_tri(seed)
    write(*, "(a, i10, 2(i10, a))") "Up to", max_peri, total, " triples",  prim, " primitives"
    if(max_peri == 100000000) exit
    max_peri = max_peri * 10
  end do
end program Pythagorean
Task: Call a foreign-language function

C: 



#include <stdio.h>

void sayHello(char* name){
    printf("Hello %s!\n", name);
}

int doubleNum(int num){
    return num * 2;
}










Fortran: module c_api
    use iso_c_binding
    implicit none

    interface
        function strdup(ptr) bind(C)
            import c_ptr
            type(c_ptr), value :: ptr
            type(c_ptr) :: strdup
        end function
    end interface
    
    interface
        subroutine free(ptr) bind(C)
            import c_ptr
            type(c_ptr), value :: ptr
        end subroutine
    end interface
    
    interface
        function puts(ptr) bind(C)
            import c_ptr, c_int
            type(c_ptr), value :: ptr
            integer(c_int) :: puts
        end function
    end interface
end module

program c_example
    use c_api
    implicit none

    character(20), target :: str = "Hello, World
    type(c_ptr) :: ptr
    integer(c_int) :: res
    
    ptr = strdup(c_loc(str))
    
    res = puts(c_loc(str))
    res = puts(ptr)
    
    print *, transfer(c_loc(str), 0_c_intptr_t), &
             transfer(ptr, 0_c_intptr_t)
    call free(ptr)
end program
Task: Extensible prime generator

C: #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#define CHUNK_BYTES (32 << 8)
#define CHUNK_SIZE (CHUNK_BYTES << 6)

int field[CHUNK_BYTES];
#define GET(x) (field[(x)>>6] &  1<<((x)>>1&31))
#define SET(x) (field[(x)>>6] |= 1<<((x)>>1&31))

typedef unsigned uint;
typedef struct {
        uint *e;
        uint cap, len;
} uarray;
uarray primes, offset;

void push(uarray *a, uint n)
{
        if (a->len >= a->cap) {
                if (!(a->cap *= 2)) a->cap = 16;
                a->e = realloc(a->e, sizeof(uint) * a->cap);
        }
        a->e[a->len++] = n;
}

uint low;
void init(void)
{
        uint p, q;

        unsigned char f[1<<16];
        memset(f, 0, sizeof(f));
        push(&primes, 2);
        push(&offset, 0);
        for (p = 3; p < 1<<16; p += 2) {
                if (f[p]) continue;
                for (q = p*p; q < 1<<16; q += 2*p) f[q] = 1;
                push(&primes, p);
                push(&offset, q);
        }
        low = 1<<16;
}

void sieve(void)
{
        uint i, p, q, hi, ptop;
        if (!low) init();

        memset(field, 0, sizeof(field));

        hi = low + CHUNK_SIZE;
        ptop = sqrt(hi) * 2 + 1;

        for (i = 1; (p = primes.e[i]*2) < ptop; i++) {
                for (q = offset.e[i] - low; q < CHUNK_SIZE; q += p)
                        SET(q);
                offset.e[i] = q + low;
        }

        for (p = 1; p < CHUNK_SIZE; p += 2)
                if (!GET(p)) push(&primes, low + p);

        low = hi;
}

int main(void)
{
        uint i, p, c;

        while (primes.len < 20) sieve();
        printf("First 20:");
        for (i = 0; i < 20; i++)
                printf(" %u", primes.e[i]);
        putchar('\n');

        while (primes.e[primes.len-1] < 150) sieve();
        printf("Between 100 and 150:");
        for (i = 0; i < primes.len; i++) {
                if ((p = primes.e[i]) >= 100 && p < 150)
                        printf(" %u", primes.e[i]);
        }
        putchar('\n');

        while (primes.e[primes.len-1] < 8000) sieve();
        for (i = c = 0; i < primes.len; i++)
                if ((p = primes.e[i]) >= 7700 && p < 8000) c++;
        printf("%u primes between 7700 and 8000\n", c);

        for (c = 10; c <= 100000000; c *= 10) {
                while (primes.len < c) sieve();
                printf("%uth prime: %u\n", c, primes.e[c-1]);
        }

        return 0;
}










Fortran:       DO WHILE(F*F <= LST)         
      DO WHILE(F <= LST/F)                      
      DO WHILE(F <= (IST + 2*(SBITS - 1))/F)    
      DO WHILE(F <= IST/F + (MOD(IST,F) + 2*(SBITS - 1))/F)
Task: Gray code

C: int gray_encode(int n) {
    return n ^ (n >> 1);
}

int gray_decode(int n) {
    int p = n;
    while (n >>= 1) p ^= n;
    return p;
}










Fortran:       PROGRAM GRAY
      IMPLICIT NONE
      INTEGER IGRAY,I,J,K
      CHARACTER*5 A,B,C
      DO 10 I=0,31
      J=IGRAY(I,1)
      K=IGRAY(J,-1)
      CALL BINARY(A,I,5)
      CALL BINARY(B,J,5)
      CALL BINARY(C,K,5)
      PRINT 99,I,A,B,C,K
   10 CONTINUE
   99 FORMAT(I2,3H : ,A5,4H => ,A5,4H => ,A5,3H : ,I2)
      END

      FUNCTION IGRAY(N,D)
      IMPLICIT NONE
      INTEGER D,K,N,IGRAY
      IF(D.LT.0) GO TO 10
      IGRAY=IEOR(N,ISHFT(N,-1))
      RETURN
   10 K=N
      IGRAY=0
   20 IGRAY=IEOR(IGRAY,K)
      K=K/2
      IF(K.NE.0) GO TO 20
      END

      SUBROUTINE BINARY(S,N,K)
      IMPLICIT NONE
      INTEGER I,K,L,N
      CHARACTER*(*) S
      L=LEN(S)
      DO 10 I=0,K-1
C The following line may replace the next block-if,
C on machines using ASCII code :
C     S(L-I:L-I)=CHAR(48+IAND(1,ISHFT(N,-I)))
C On EBCDIC machines, use 240 instead of 48.
      IF(BTEST(N,I)) THEN
      S(L-I:L-I)='1'
      ELSE
      S(L-I:L-I)='0'
      END IF
   10 CONTINUE
      S(1:L-K)=''
      END
Task: File extension is in extensions list

C: 

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <locale.h>
#include <string.h>

#ifdef _Bool
#include <stdbool.h>
#else
#define bool int
#define true  1
#define false 0
#endif


int checkFileExtension(char* fileName, char* fileExtensions)
{
    char* fileExtension = fileExtensions;

    if ( *fileName )
    {
        while ( *fileExtension )
        {
            int fileNameLength = strlen(fileName);
            int extensionLength = strlen(fileExtension);
            if ( fileNameLength >= extensionLength )
            {
                char* a = fileName + fileNameLength - extensionLength;
                char* b = fileExtension;
                while ( *a && toupper(*a++) == toupper(*b++) )
                    ;
                if ( !*a )
                    return true;
            }
            fileExtension += extensionLength + 1;
        }
    }
    return false;
}

void printExtensions(char* extensions)
{
    while( *extensions )
    {
        printf("%s\n", extensions);
        extensions += strlen(extensions) + 1;
    }
}

bool test(char* fileName, char* extension, bool expectedResult)
{
    bool result = checkFileExtension(fileName,extension);
    bool returnValue = result == expectedResult;
    printf("%20s  result: %-5s  expected: %-5s  test %s\n", 
        fileName,
        result         ? "true"   : "false",
        expectedResult ? "true"   : "false", 
        returnValue    ? "passed" : "failed" );
    return returnValue;
}

int main(void)
{
    static char extensions[] = ".zip\0.rar\0.7z\0.gz\0.archive\0.A##\0.tar.bz2\0";

    setlocale(LC_ALL,"");

    printExtensions(extensions);
    printf("\n");

    if ( test("MyData.a##",         extensions,true )
    &&   test("MyData.tar.Gz",      extensions,true )
    &&   test("MyData.gzip",        extensions,false)
    &&   test("MyData.7z.backup",   extensions,false)
    &&   test("MyData...",          extensions,false)
    &&   test("MyData",             extensions,false)
    &&   test("MyData_v1.0.tar.bz2",extensions,true )
    &&   test("MyData_v1.0.bz2",    extensions,false) 
    &&   test("filename",           extensions,false)
    )
        printf("\n%s\n", "All tests passed.");
    else
        printf("\n%s\n", "Last test failed.");

    printf("\n%s\n", "press enter");
    getchar();
    return 0;
}










Fortran:         IT = ICHAR(TEXT(I:I)) - ICHAR("a")	
        IF (IT.GE.0 .AND. IT.LE.25) TEXT(I:I) = CHAR(IT + ICHAR("A"))
Task: Extreme floating point values

C: #include <stdio.h>

int main()
{
    double inf = 1/0.0;
    double minus_inf = -1/0.0;
    double minus_zero = -1/ inf ;
    double nan = 0.0/0.0;

    printf("positive infinity: %f\n",inf);
    printf("negative infinity: %f\n",minus_inf);
    printf("negative zero: %f\n",minus_zero);
    printf("not a number: %f\n",nan);

    

    printf("+inf + 2.0 = %f\n",inf + 2.0);
    printf("+inf - 10.1 = %f\n",inf - 10.1);
    printf("+inf + -inf = %f\n",inf + minus_inf);
    printf("0.0 * +inf = %f\n",0.0 * inf);
    printf("1.0/-0.0 = %f\n",1.0/minus_zero);
    printf("NaN + 1.0 = %f\n",nan + 1.0);
    printf("NaN + NaN = %f\n",nan + nan);

    

    printf("NaN == NaN = %s\n",nan == nan ? "true" : "false");
    printf("0.0 == -0.0 = %s\n",0.0 == minus_zero ? "true" : "false");

    return 0;
}










Fortran:        REAL*8		BAD,NaN			
       PARAMETER (NaN = Z'FFFFFFFFFFFFFFFF')	
       PARAMETER (BAD = Z'FFFFFFFFFFFFFFFF')	
       CHARACTER*3	BADASTEXT		
       DATA		BADASTEXT/" ? "/	
       REAL*8		PINF,NINF		
       PARAMETER (PINF = Z'7FF0000000000000')	
       PARAMETER (NINF = Z'FFF0000000000000')
Task: Flow-control structures

C: int main()
{
  int i,j;
  for (j=1; j<1000; j++) {
    for (i=0; i<j, i++) {
      if (exit_early())
        goto out;
      
    }
  }
out:
  return 0;
}










Fortran:       ...
      ASSIGN 1101 to WHENCE   
      GO TO 1000              
 1101 CONTINUE                
      ... 
      ASSIGN 1102 to WHENCE   
      GO TO 1000              
 1102 CONTINUE                
      ...
Common code, far away.
 1000 do something            
      GO TO WHENCE
Task: Return multiple values

C: #include<stdio.h>

typedef struct{
	int integer;
	float decimal;
	char letter;
	char string[100];
	double bigDecimal;
}Composite;

Composite example()
{
	Composite C = {1, 2.3, 'a', "Hello World", 45.678};
	return C;
}


int main()
{
	Composite C = example();

	printf("Values from a function returning a structure : { %d, %f, %c, %s, %f}\n", C.integer, C.decimal, C.letter, C.string, C.bigDecimal);

	return 0;
}










Fortran: module multiple_values
implicit none
type res
  integer :: p, m
end type

contains

function addsub(x,y) result(r)
  integer :: x, y
  type(res) :: r 
  r%p = x+y
  r%m = x-y
end function
end module

program main
  use multiple_values 
  print *, addsub(33, 22)
end program
Task: Fractran

C: #include <stdio.h>
#include <stdlib.h>
#include <gmp.h>

typedef struct frac_s *frac;
struct frac_s {
	int n, d;
	frac next;
};

frac parse(char *s)
{
	int offset = 0;
	struct frac_s h = {0}, *p = &h;

	while (2 == sscanf(s, "%d/%d%n", &h.n, &h.d, &offset)) {
		s += offset;
		p = p->next = malloc(sizeof *p);
		*p = h;
		p->next = 0;
	}

	return h.next;
}

int run(int v, char *s)
{
	frac n, p = parse(s);
	mpz_t val;
	mpz_init_set_ui(val, v);

loop:	n = p;
	if (mpz_popcount(val) == 1)
		gmp_printf("\n[2^%d = %Zd]", mpz_scan1(val, 0), val);
	else
		gmp_printf(" %Zd", val);

	for (n = p; n; n = n->next) {
		
		if (!mpz_divisible_ui_p(val, n->d)) continue;

		mpz_divexact_ui(val, val, n->d);
		mpz_mul_ui(val, val, n->n);
		goto loop;
	}

	gmp_printf("\nhalt: %Zd has no divisors\n", val);

	mpz_clear(val);
	while (p) {
		n = p->next;
		free(p);
		p = n;
	}

	return 0;
}

int main(void)
{
	run(2,	"17/91 78/85 19/51 23/38 29/33 77/29 95/23 "
		"77/19 1/17 11/13 13/11 15/14 15/2 55/1");

	return 0;
}










Fortran: C:\Nicky\RosettaCode\FRACTRAN\FRACTRAN.for(6) : Warning: This name has not been given an explicit type.   [M]
       INTEGER P(M),Q(M)
Task: Substring_Top and tail

C: #include <string.h>
#include <stdlib.h>
#include <stdio.h>

int main( int argc, char ** argv ){
  const char * str_a = "knight";
  const char * str_b = "socks";
  const char * str_c = "brooms";

  char * new_a = malloc( strlen( str_a ) - 1 );
  char * new_b = malloc( strlen( str_b ) - 1 );
  char * new_c = malloc( strlen( str_c ) - 2 );

  strcpy( new_a, str_a + 1 );
  strncpy( new_b, str_b, strlen( str_b ) - 1 );
  strncpy( new_c, str_c + 1, strlen( str_c ) - 2 );

  printf( "%s\n%s\n%s\n", new_a, new_b, new_c );

  free( new_a );
  free( new_b );
  free( new_c );

  return 0;
}










Fortran: program substring

  character(len=5) :: string
  string = "Hello"
  
  write (*,*) string
  write (*,*) string(2:)
  write (*,*) string( :len(string)-1)
  write (*,*) string(2:len(string)-1)

end program substring
Task: Boolean values

C: int a = 0;
int b = 1;
int c;
string str1 = "initialized string";
string str2; 

if (a) {puts("first test a is false");}         
if (b) {puts("second test b is true");}         
if (c) {puts("third test b is false");}         
if (!defined(c)) {puts("fourth test is true");} 
if (str1) {puts("fifth test str1 is true");}    
if (str2) {puts("sixth test str2 is false");}   










Fortran:       TYPE MIXED
       LOGICAL*1 LIVE
       REAL*8    VALUE
      END TYPE MIXED
      TYPE(MIXED) STUFF(100)
Task: Bitmap_Histogram

C: typedef unsigned int histogram_t;
typedef histogram_t *histogram;

#define GET_LUM(IMG, X, Y) ( (IMG)->buf[ (Y) * (IMG)->width + (X)][0] )

histogram get_histogram(grayimage im);
luminance histogram_median(histogram h);










Fortran: module RCImageProcess
  use RCImageBasic
  implicit none
contains

  subroutine get_histogram(img, histogram)
    type(scimage), intent(in) :: img
    integer, dimension(0:255), intent(out) :: histogram
    
    integer :: i

    histogram = 0
    do i = 0,255
       histogram(i) = sum(img%channel, img%channel == i)
    end do
  end subroutine get_histogram

  function histogram_median(histogram)
    integer, dimension(0:255), intent(in) :: histogram
    integer :: histogram_median
    
    integer :: from, to, left, right

    from = 0
    to = 255
    left = histogram(from)
    right = histogram(to)
    do while ( from /= to )
       if ( left < right ) then
          from = from + 1
          left = left + histogram(from)
       else
          to = to - 1
          right = right + histogram(to)
       end if
    end do
    histogram_median = from
  end function histogram_median
  
end module RCImageProcess