Whats wrong with my code? The backwards loop doesnt work (Option 2) - slider

The option (2) crashes/overloads my coding software, it has the same code as option (1), does anybody know why its doing it and how to fix it?
#include "aservelibs/aservelib.h"
#include <stdio.h>
#include <math.h>
int length();
float mtof(int note);
int main() {
// do while the user hasnt pressed exit key (whatever)
int control[8] = {74, 71, 91, 93, 73, 72, 5, 84};
int index;
int mod;
float frequency;
int notes[8];
int response;
mod = aserveGetControl(1);
// ask backwards, forwards, exit
// SCALING
// (getControl(75) / ((127 - 0) / (1000 - 100))) + 100;
while(true) {
printf("Run Loop Forwards (1), Backwards (2), Exit (0)\n");
scanf("%d", &response);
if(response == 1) {
while(mod == 0) {
for(index = 0; index < 8; index++) {
notes[index] = aserveGetControl(control[index]);
frequency = mtof(notes[index]);
aserveOscillator(0, frequency, 1.0, 0);
aserveSleep(length());
printf("Slider Value:%5d\n", notes[index]);
mod = aserveGetControl(1);
}
}
} else if(response == 2) {
// here is the part where the code is exactly
// the same apart from the for loop which is
// meant to make the loop go backwards
while(mod == 0) {
for(index = 8; index > 0; index--) {
notes[index] = aserveGetControl(control[index]);
frequency = mtof(notes[index]);
aserveOscillator(0, frequency, 1.0, 0);
aserveSleep(length());
printf("Slider Value:%5d\n", notes[index]);
mod = aserveGetControl(1);
}
}
} else if(response == 0) {
return 0;
}
}
}
int length() {
return (aserveGetControl(75)/((127.0 - 0) / (1000 - 100))) + 100;
}
float mtof(int note) {
return 440 * pow(2, (note-69) / 12.0);
}

Your for loops aren't exactly the same.
The first option goes through { 0, 1, ..., 7 }
The second option goes through { 8, 7, ..., 1 }
Notice also that control[8] is undefined (0..7). So when it tries to reference this location the application runs into an error.
Change the second for loop to
for (index = 7; index >= 0; index--) {
...
}

Related

TinkerCAD Ardunio code error too few arguments

I'm building a robot for my class, and we have to have 2 servos and 1 DC motor working in a specific way. Everything is hooked up to an arduino uno, and my code works, but I using tinkercad to test a few things but I'm getting an error which is stopping my code from functioning in tinker cad, and I'm at a total loss.
ERROR
In function 'void loop()':
44:9: error: too few arguments to function 'void motor(char, char)'
17:6: note: declared here
exit status 1
CODE
#include <Servo.h> // set servo header to let ardduino know you intend to use a servo
Servo mycontinuousservo; // declare servos to be used
Servo mydegreeservo;
int In1 = 7; // declare your global variables to indicate pin numbers
int In2 = 8;
int pin = 6;
int servocontinuouspin = 10;
int servodegreepin = 9;
int angle = 90;
void servopos();
void servocontinous();
void motor(char Speed,char Direction);
void setup() {
// put your setup code here, to run once:
pinMode(In1, OUTPUT);
pinMode(In2, OUTPUT);
pinMode(pin, OUTPUT);
digitalWrite(In1, HIGH); //pin 7 moves forward
digitalWrite(In2, LOW); //pin 8 moves forward
analogWrite(pin, 0); // start at 0
pinMode(servocontinuouspin, OUTPUT);
pinMode(servodegreepin, OUTPUT);
mycontinuousservo.attach(servocontinuouspin);
mydegreeservo.attach(servodegreepin);
mycontinuousservo.write(90);
Serial.begin(9600); // for serial communication
}
void loop() {
servocontinous(); //call by ref aforedeclared functions
servopos();
motor();
}
// EXIT THE LOOP
void servopos() { //position function
int degree = 0;
int i = 0;
for (i = 0; i < 18; i++) {
mydegreeservo.write(degree);
delay(500); //delay 0.5 seconds
degree = degree + 10;
}
}
void servocontinous() // continous servo settings
{
for (int angle = 90; angle >= 0; angle--) {
mycontinuousservo.write(angle);
delay(50);
}
if (angle == 0) {
Serial.print("speed\n");
}
for (angle = 0; angle < 90; angle++)
{
mycontinuousservo.write(angle);
delay(50);
}
}
void motor() //motor function
{
char Speed = 0;
char Direction = 0;
if (Serial.available() > 0) //initialising
{
if (Direction == 'f') //70 representing F on the ASCII table
{
delay(500);
Serial.println("F");
}
if (Direction == 'r')
{
delay(500);
Serial.println("R");
}
}
if (Serial.available() > 0)
{
Speed = Serial.read();
if (Speed == '0')
{
Speed = 0;
Serial.println("Speed 0");
}
if (Speed == '1')
{
Speed = 14;
Serial.println("Speed 1");
}
if (Speed == '2')
{
Speed = 29;
Serial.println("Speed 2");
}
if (Speed == '3')
{
Speed = 42;
Serial.println("Speed 3");
}
if (Speed == '4')
{
Speed = 56;
Serial.println("Speed 4");
}
if (Speed == '5')
{
Speed = 70;
Serial.println("Speed 5");
}
if (Speed == '6')
{
Speed = 84;
Serial.println("Speed 6");
}
if (Speed == '7')
{
Speed = 98;
Serial.println("Speed 7");
}
if (Speed == '8')
{
Speed = 112;
Serial.println("Speed 8");
}
if (Speed == '9')
{
Speed = 128;
Serial.println("Speed 9");
}
} delay(5000);
analogWrite(pin, Speed);
if (Direction == 'f')
{ digitalWrite(In1, HIGH);
digitalWrite(In2, LOW);
} if (Direction == 'r')
{
digitalWrite(In1, LOW);
digitalWrite(In2, HIGH);
}
}
Here you declare the function as taking two arguments:
void motor(char Speed,char Direction);
Later you call it with no arguments, which is invalid when compared to that declaration:
motor();
This will be an immediate compiler error. That function is described as having two arguments, you call it with zero. Compile hard fails and stops because of this contradiction.
Yet when you define it the arguments are gone, they're actually local variables:
void motor() //motor function
{
char Speed = 0;
char Direction = 0;
// ...
}
This too contradicts the earlier declaration, so if you comment out the place where it's called you'll likely get a different error.
Local variables are the private business of a function, they do not need to be shown in the function signature, so don't think these need to be included as arguments.
What you need to do is either snip the arguments from the declaration, make sure that declaration matches the function signature exactly, or move the motor() function definition to before where it is first called.
I prefer to organize things so that pre-declaration is not necessary, or at least minimized. There's no reason to not put the motor() definition before loop().

Exception thrown at 0x7A12FF80 (ucrtbased.dll) in Project 3.exe: 0xC0000005: Access violation reading location 0x00000000

I have attempted to run this code. Prior to running this, no warnings or errors exist but once it is executed I have an exception thrown and it stops the program from compiling. Here is my code and the error is in the subject line. The CDA file is being used as header file to create a Circular Dynamic Array that is going to be manipulated in Heaps.cpp. The heaps.cpp is to create a binary heap that is to be used in to create Binomial heaps, but that code has not been developed yet.
#include <iostream>
using namespace std;
template <class T>
class CDA
{
private:
int rear;
int size;
int capacity;
T* circArray;
int front;
bool ordered;
T placeHolder;
public:
CDA();
CDA(int s);
~CDA();
int Front();
T Data(int n);
T& operator[](int i);
void AddEnd(T v);
void AddFront(T v);
void DelEnd();
void DelFront();
int Length();
int Capacity();
int Clear();
bool Ordered();
int SetOrdered();
int S01(int n);
T Select(int k);
void InsertionSort();
void QuickSort();
void QuickSort1(int low, int high);
void CountingSort(int m);
int Search(T e);
void reSize();
void Shrink();
int BinarySearch(int left, int right, T e);
int QSortPartition(int low, int high);
void Swap(int* x, int* y);
int QSelPartition(int front, int rear);
T QuickSelect(int front, int rear, int k);
CDA<T>& operator=(const CDA& a);
CDA(const CDA& old);
int Median(int low, int high);
};
template <class T>
CDA<T>::CDA()
{
capacity = 1;
circArray = new T[capacity];
size = 0;
rear = size - 1;
front = -1;
ordered = false;
placeHolder = 0;
}
template <class T>
CDA<T>::CDA(int s)
{
size = s;
capacity = s;
circArray = new T[capacity];
front = 0;
rear = size - 1;
ordered = false;
}
template <class T>
CDA<T>::CDA(const CDA& a)
{
size = a.size;
capacity = a.capacity;
circArray = new T[a.capacity];
front = a.front;
rear = a.size - 1;
ordered = a.ordered;
for (int i = a.front; i < a.front + (a.size); i++)
{
circArray[i % capacity] = a.circArray[i % capacity];
}
}
template <class T>
CDA<T>::~CDA()
{
delete[]circArray;
}
template <class T>
T& CDA<T>::operator[](int i)
{
if (i > capacity)
{
cout << "Array index is out of bounds; exiting." << endl;
placeHolder = i;
cout << endl;
return placeHolder;
exit(0);
}
else
{
return circArray[(front + i) % capacity];
}
}
template <class T>
void CDA<T>::AddEnd(T v)
{
size++;
if (front == -1)
{
circArray[0] = v;
front++;
rear++;
return;
}
if (size > capacity)
{
reSize();
}
else if (front == -1)
{
front = 0;
rear = size - 1;
}
else
{
rear = (rear + 1) % capacity;
}
circArray[rear] = v;
}
template <class T>
void CDA<T>::AddFront(T v)
{
size++;
if (size > capacity)
{
reSize();
}
if (front == -1) //means the array is empty
{
front = 0;
rear = capacity % size;
}
else if (front == 0) //means something is in spot 0
{
front = capacity - 1; //puts front at the end and places the input there
}
else //go until it is back at zero
{
front--;
}
circArray[front] = v;
}
template <class T>
void CDA<T>::DelEnd()
{
size--;
if (size <= capacity / 4)
{
Shrink();
}
else if (rear == front)
{
front = -1;
rear = -1;
}
else
{
rear--;
}
}
template <class T>
void CDA<T>::DelFront()
{
size--;
double shrMeasure;
shrMeasure = capacity / 4.0;
if (size <= shrMeasure) // make an empty and shrink function
{
Shrink();
}
/*
else if (front == rear)
{
if (front == 0)
front = size - 1;
else
front++;
}
*/
else
{
if (front == size) //brings it full circle
{
front = 0;
}
else
{
front++;
}
}
if (front > capacity)
front = front % capacity;
}
template <class T>
int CDA<T>::Length()
{
return size;
}
template <class T>
int CDA<T>::Capacity()
{
return capacity;
}
template <class T>
int CDA<T>::Clear()
{
~CDA();
size = 1;
circArray[size] = NULL;
}
template <class T>
bool CDA<T>::Ordered()
{
return ordered;
}
template <class T>
int CDA<T>::SetOrdered()
{
for (int i = 1; i < size - 1; i++)
{
if (circArray[(i - 1)] > circArray[i])
{
ordered = false;
return -1;
}
}
ordered = true;
return 1;
}
template <class T>
T CDA<T>::Select(int k)
{
if (ordered == true)
{
return circArray[(front + k - 1) % capacity];
}
else
QuickSelect(front, front + (size - 1), k);
}
template <class T>
int CDA<T>::QSelPartition(int left, int right)
{
int pivot = circArray[right % capacity];
int x = left - 1;
//Swap(&circArray[pivIndex], &circArray[right]);
for (int i = left; i <= right - 1; i++)
{
if (circArray[i % capacity] <= pivot)
{
x++;
Swap(&circArray[x % capacity], &circArray[i % capacity]);
}
}
Swap(&circArray[(x + 1) % capacity], &circArray[right % capacity]);
return (x + 1);
}
template <class T>
T CDA<T>::QuickSelect(int left, int right, int k)
{
if (k > 0 && k <= (right - left) + 1)
{
int index = QSelPartition(left, right);
if (index - 1 == k - 1)
return circArray[index % capacity];
else if (index - 1 > k - 1)
return QuickSelect(left, index - 1, k);
else
return QuickSelect(index - 1, right, k - index + left - 1);
}
return -1;
}
template <class T>
void CDA<T>::InsertionSort() //must be utilized in quicksort
{
for (int i = front + 1; i < (front + size); i++)
{
int val = circArray[i % capacity];
int inc = (i - 1) % capacity;
while (inc >= 0 && circArray[inc] > val)
{
circArray[(inc + 1) % capacity] = circArray[inc];
inc--;
if (inc == -1)
{
inc = capacity - 1;
}
}
circArray[(inc + 1) % capacity] = val;
}
ordered = true;
}
template <class T>
void CDA<T>::QuickSort() // change to other quicksort before leaving the ferg
{
QuickSort1(front, front + (size - 1));
}
template <class T>
void CDA<T>::QuickSort1(int low, int high)
{
while (low < high)
{
if (high - low < 900)
{
InsertionSort();
break;
}
else
{
int pivot = QSortPartition(low, high);
if (pivot - low < high - pivot)
{
QuickSort1(low, pivot--);
low = pivot + 1;
}
else
{
QuickSort1(pivot++, high);
high = pivot - 1;
}
}
}
}
template <class T>
int CDA<T>::QSortPartition(int low, int high)
{
int pivot = circArray[Median(low, high) % capacity];
Swap(&circArray[(Median(low, high)) % capacity], &circArray[(high) % capacity]);
int index = low % capacity;
for (int i = low; i < high; i++)
{
if (circArray[i % capacity] <= pivot)
{
T t = circArray[i % capacity];
circArray[i % capacity] = circArray[index % capacity];
circArray[index % capacity] = t;
index++;
}
}
Swap(&circArray[index % capacity], &circArray[high % capacity]);
return index;
}
template <class T>
int CDA<T>::Median(int low, int high)
{
T left, mid, right;
left = circArray[low % capacity];
mid = circArray[((low + high) / 2) % capacity];
right = circArray[high % high];
if (left < right && left > mid)
return low % capacity;
if (left < mid && left > right)
return low % capacity;
if (right < left && right > mid)
return high % capacity;
if (right < mid && right > left)
return high % capacity;
if (mid < left && mid > right)
return ((low + high) / 2 % capacity);
if (mid < right && mid > left)
return ((low + high) / 2 % capacity);
}
template <class T>
void CDA<T>::Swap(int* x, int* y)
{
int temp = *x;
*x = *y;
*y = temp;
}
template <class T>
void CDA<T>::CountingSort(int m) ////NEED TO FIX THIS
{
int* OP = new int[size];
int* Counter = new int[m + 1];
for (int i = front; i <= rear; i++)
{
cout << "CircArray[" << i << "] is " << circArray[i] << endl;
}
for (int i = 0; i <= m; i++)
{
Counter[i] = 0;
}
for (int i = front; i < front + (size); i++)
{
Counter[circArray[i % capacity]]++;
}
for (int i = 1; i <= m; i++)
{
Counter[i] += Counter[i - 1];
}
for (int i = rear - 1; i > 0; i--)
{
OP[Counter[circArray[i]] - 1] = circArray[i];
cout << "Circular array at " << i << " is " << circArray[i] << endl;
Counter[circArray[i]] -= 1;
if (i == front % capacity)
break;
if (i == 0)
i = capacity;
}
for (int i = 0; i < size; i++)
circArray[i] = OP[i];
ordered = true;
front = 0;
}
template <class T>
int CDA<T>::Search(T e)
{
if (ordered == true) //binary search of item e
{
return BinarySearch(front, front + (size - 1), e);
}
else if (ordered == false)
{
for (int i = 0; i < size - 1; i++)
{
if (circArray[i] == e)
return i;
}
}
return -1;
}
template <class T>
int CDA<T>::BinarySearch(int left, int right, T e)
{
while (left <= right)
{
int mid = (left + right) / 2;
int value = circArray[mid % capacity];
if (value == e)
return (mid - front) % capacity;
else if (value < e)
return BinarySearch(mid + 1, right, e);
else if (value > e)
return BinarySearch(left, mid - 1, e);
}
return -1;
}
template <class T>
void CDA<T>::reSize()
{
capacity = capacity * 2;
T *nArray = new T[capacity];
for (int i = 0; i < size - 1; i++)
{
int l = (front + i) % (size-1);
nArray[i] = circArray[l];
}
//delete[]circArray;
circArray = nArray;
front = 0;
rear = (size - 1);
}
template <class T>
void CDA<T>::Shrink()
{
int tFront = front;
capacity = capacity / 2;
T* bArr = new T[capacity];
int index = 0;
while (front <= rear)
{
bArr[index] = circArray[(front + index) % capacity];
index++;
}
T* circArray = bArr;
front = 0;
rear = (size - 1);
}
template <class T>
CDA<T>& CDA<T>::operator=(const CDA<T>& a)
{
if (this != &a)
{
delete[]circArray;
size = a.size;
capacity = a.capacity;
circArray = new T[a.capacity];
front = a.front;
rear = a.size - 1;
ordered = a.ordered;
for (int i = a.front; i < a.front + (a.size); i++)
{
circArray[i % capacity] = a.circArray[i % capacity];
}
}
return *this;
}
template <class T>
int CDA<T>::Front()
{
return front;
}
template <class T>
T CDA<T>::Data(int n)
{
return circArray[n];
}
#include <iostream>
#include "CDA-1.cpp"
using namespace std;
template<class keytype, class valuetype>
class Heap
{
private:
CDA<keytype>* K;
CDA<valuetype>* V;
int size;
public:
Heap()
{
this->K = new CDA<keytype>();
this->V = new CDA<valuetype>();
size = 0;
}
Heap(keytype k[], valuetype v[], int s)
{
//allocate two different arrays for each type
//fill those arrays concurrently using insert
//sort concurrently using heapafy recursively
this->K = new CDA<keytype>(s);
this->V = new CDA<valuetype>(s);
this->size = s;
for (int i = 0; i < s; i++)
{
insert(k[i], v[i]);
}
heapify(s, K->Front());
}
void heapify(int s, int i)
{
//Errors for evans to fix: swap the n's with s.
//Fix the left and right variable logic. Hepaify smallest not small at the bottom.
//Also we need to pass V[] in a parameter so we can edit it in this.
//How to better swap V with K and not just K.
int smallest = i;
int left = 2*i +(-i+1);
int right = 2*i + (-i+2);
keytype kl = K->Data(left);
keytype kr = K->Data(right);
keytype ks = K->Data(smallest);
if (left < s && kl < ks) //FIX
smallest = left;
if (right < s && kr < ks) //FIX
smallest = right;
if (smallest != i)
{
swap(K[i], K[smallest]);
swap(V[i], V[smallest]); //FIX
heapify(s, smallest);
}
}
~Heap() {
return;
}
//items should be inserted using bottom up heap building method
void insert(keytype k, valuetype v)
{
K->AddEnd(k);
V->AddEnd(v);
heapify(size, K->Front());
}
keytype peekKey()
{
int f = K->Front();
return K->Data(f);
}
valuetype peekValue()
{
int f = V->front();
return V->Data(f);
}
keytype extractMin()
{
keytype temp = K->Data(K->Front());
K->DelFront();
V->DelFront();
heapify(size, K->Front());
return temp;
}
void printKey()
{
ActualPrintKey(K->Front());
}
void ActualPrintKey(int n)
{
keytype rt = K->Data(n);
if (rt != size)
{
cout << K->Data(rt) << " ";
ActualPrintKey((2 * n) + (-n + 1));
ActualPrintKey((2 * n) + (-n + 2));
}
}
};
/*
template <class keytype, class valuetype>
class BHeap
{
BHeap();
BHeap(keytype k[], valuetype v[], int s);
~BHeap();
keytype peekKey();
valuetype peekValue();
keytype extractMin();
//items should be inserted using repeated insertion
void insert(keytype k, valuetype v);
void merge(BHeap<keytype, valuetype>& H2);
void printKey();
};
*/
#include <iostream>
#include "Heaps.cpp"
using namespace std;
int main() {
string K[10] = { "A", "B", "C", "D", "E", "F", "G", "H", "I", "K" };
int V[10] = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
Heap<string, int> T1, T2(K, V, 10);
cout << T2.peekKey() << endl;
cout << endl;
system("pause");
return 0;
}
In general "Access violation reading location", means you are trying to read virtually memory address space to a process which does not belong to your application and the operating system protective mechanism is kicking in to protect the rest of the loaded applications and resource from been accessed (read or write) by your application "memory leak vulnerability". If I was at your place I would review the code and all variables and arrays if they are properly initialized before use. Another thing which needs to be taken in consideration is the operating system and the permissions required by your application (Windows run as Administrator / GNU/Linux sudo).
Cheers

Have to compare equality of 5 numbers and choose best of 3 in case in C

I have a situation where i have to write a code to compare 5 integers to see which ones are equal and choose atleast 3 equal numbers of the 5 nrs. More than:-
e.g.
a=0,b=0,c=0,d=2,c=3
then Valid_nr=0,
a=6,b=0,c=6,d=6,c=6
then Valid_nr=6,
a=8,b=8,c=8,d=8,c=8
then Valid_nr=8
Please suggest me some logic because this seems to be very confusing to write a short and efficient code to achieve this..
Example written in C#:
class Program
{
static List<int> numbers = new List<int>();
static int NumOfequals = 1;
static int ValidNUmber;
static void Main(string[] args)
{
for (int i=0;i<5;i++)
{
int input;
Console.WriteLine("Enter number " + (i+1).ToString() + "and press enter");
if (int.TryParse(Console.ReadLine(),out input))
{
numbers.Add(input);
}
else
{
Console.WriteLine("not an integer");
}
}
numbers.Sort();
for (int i=0;i<numbers.Count;i++)
{
if (i<numbers.Count-1)
{
if (numbers[i]==numbers[i+1])
{
NumOfequals++;
ValidNumber=numbers[i];
}
else
{
if (NumOfequals < 3)
{
NumOfequals = 1;
ValidNumber=-1;
}
}
}
}
Console.WriteLine("number of equal numbers is " + NumOfequals.ToString()+" and the valid number is:"+ValidNumber.ToString());
Console.ReadLine();
}
}
I'll show you a function in C that generalize the problem in your question, equalities() compares the elements of an array of int and return the maximum number of equalities. A pointer to an int is passed too to store the value of the repeted number. You can easily specialize this function for your problem or use it as it is and check if the returned value is >= 3 only.
#include <stdio.h>
#include <stdlib.h>
int equalities( int *nums, int n, int *x ) {
int * vals = malloc(n * sizeof(int));
int * reps = calloc(n,sizeof(int));
int i,j;
for ( i = 0; i < n; ++i ) {
for ( j = 0; j < n && reps[j] != 0 && vals[j] != nums[i]; ++j );
if ( j != 0 && reps[j] == reps[0]) { // new max
vals[j] = vals[0];
vals[0] = nums[i];
++reps[0];
} else {
vals[j] = nums[i];
++reps[j];
}
}
*x = vals[0];
int rep = reps[0];
free(vals);
free(reps);
return rep;
}
int main(void) {
int test1[] = { 1, 4, 2, 4, 4 };
int test2[] = { 0, 0, 2, 0, 0 };
int test3[] = { 1, 3, 2, 4, 5 };
int test4[] = { 1, 1, 1, 1, 1 };
int test5[] = { 5, 5, 0, 5, 0 };
int y = -1;
int r = equalities(test1,5,&y);
printf("Repetitions: %d, Number: %d\n",r,y);
r = equalities(test2,5,&y);
printf("Repetitions: %d, Number: %d\n",r,y);
r = equalities(test3,5,&y);
printf("Repetitions: %d, Number: %d\n",r,y);
r = equalities(test4,5,&y);
printf("Repetitions: %d, Number: %d\n",r,y);
r = equalities(test5,5,&y);
printf("Repetitions: %d, Number: %d\n",r,y);
return 0;
}
The output of the test main() is:
Repetitions: 3, Number: 4
Repetitions: 4, Number: 0
Repetitions: 1, Number: 1
Repetitions: 5, Number: 1
Repetitions: 3, Number: 5

mupdf render jpeg2000 lose color?

I am working on an android project, which use vudroid, which in turn use mupdf version 0.5.
Vudroid remove the original openjpeg support of mupdf, I have ported the mupdf version 1.5's openjpeg support.
But I encounter a new problem, color information in jpx image gone, the desired effect:
my effect:
the ported load-jpx code:
#include "fitz.h"
#include "mupdf.h"
/* Without the definition of OPJ_STATIC, compilation fails on windows
* due to the use of __stdcall. We believe it is required on some
* linux toolchains too. */
#define OPJ_STATIC
#ifndef _MSC_VER
#define OPJ_HAVE_STDINT_H
#endif
#include <openjpeg.h>
static void fz_opj_error_callback(const char *msg, void *client_data)
{
//fz_context *ctx = (fz_context *)client_data;
//fz_warn(ctx, "openjpeg error: %s", msg);
}
static void fz_opj_warning_callback(const char *msg, void *client_data)
{
//fz_context *ctx = (fz_context *)client_data;
//fz_warn(ctx, "openjpeg warning: %s", msg);
}
static void fz_opj_info_callback(const char *msg, void *client_data)
{
/* fz_warn("openjpeg info: %s", msg); */
}
typedef struct stream_block_s
{
unsigned char *data;
int size;
int pos;
} stream_block;
static OPJ_SIZE_T fz_opj_stream_read(void * p_buffer, OPJ_SIZE_T p_nb_bytes, void * p_user_data)
{
stream_block *sb = (stream_block *)p_user_data;
int len;
len = sb->size - sb->pos;
if (len < 0)
len = 0;
if (len == 0)
return (OPJ_SIZE_T)-1; /* End of file! */
if ((OPJ_SIZE_T)len > p_nb_bytes)
len = p_nb_bytes;
memcpy(p_buffer, sb->data + sb->pos, len);
sb->pos += len;
return len;
}
static OPJ_OFF_T fz_opj_stream_skip(OPJ_OFF_T skip, void * p_user_data)
{
stream_block *sb = (stream_block *)p_user_data;
if (skip > sb->size - sb->pos)
skip = sb->size - sb->pos;
sb->pos += skip;
return sb->pos;
}
static OPJ_BOOL fz_opj_stream_seek(OPJ_OFF_T seek_pos, void * p_user_data)
{
stream_block *sb = (stream_block *)p_user_data;
if (seek_pos > sb->size)
return OPJ_FALSE;
sb->pos = seek_pos;
return OPJ_TRUE;
}
fz_error
fz_load_jpx(pdf_image* img, unsigned char *data, int size, fz_colorspace *defcs, int indexed)
{
//fz_pixmap *img;
opj_dparameters_t params;
opj_codec_t *codec;
opj_image_t *jpx;
opj_stream_t *stream;
fz_colorspace *colorspace;
unsigned char *p;
OPJ_CODEC_FORMAT format;
int a, n, w, h, depth, sgnd;
int x, y, k, v;
stream_block sb;
if (size < 2)
fz_throw("not enough data to determine image format");
/* Check for SOC marker -- if found we have a bare J2K stream */
if (data[0] == 0xFF && data[1] == 0x4F)
format = OPJ_CODEC_J2K;
else
format = OPJ_CODEC_JP2;
opj_set_default_decoder_parameters(&params);
if (indexed)
params.flags |= OPJ_DPARAMETERS_IGNORE_PCLR_CMAP_CDEF_FLAG;
codec = opj_create_decompress(format);
opj_set_info_handler(codec, fz_opj_info_callback, 0);
opj_set_warning_handler(codec, fz_opj_warning_callback, 0);
opj_set_error_handler(codec, fz_opj_error_callback, 0);
if (!opj_setup_decoder(codec, &params))
{
fz_throw("j2k decode failed");
}
stream = opj_stream_default_create(OPJ_TRUE);
sb.data = data;
sb.pos = 0;
sb.size = size;
opj_stream_set_read_function(stream, fz_opj_stream_read);
opj_stream_set_skip_function(stream, fz_opj_stream_skip);
opj_stream_set_seek_function(stream, fz_opj_stream_seek);
opj_stream_set_user_data(stream, &sb);
/* Set the length to avoid an assert */
opj_stream_set_user_data_length(stream, size);
if (!opj_read_header(stream, codec, &jpx))
{
opj_stream_destroy(stream);
opj_destroy_codec(codec);
fz_throw("Failed to read JPX header");
}
if (!opj_decode(codec, stream, jpx))
{
opj_stream_destroy(stream);
opj_destroy_codec(codec);
opj_image_destroy(jpx);
fz_throw("Failed to decode JPX image");
}
opj_stream_destroy(stream);
opj_destroy_codec(codec);
/* jpx should never be NULL here, but check anyway */
if (!jpx)
fz_throw("opj_decode failed");
pdf_logimage("opj_decode succeeded");
for (k = 1; k < (int)jpx->numcomps; k++)
{
if (!jpx->comps[k].data)
{
opj_image_destroy(jpx);
fz_throw("image components are missing data");
}
if (jpx->comps[k].w != jpx->comps[0].w)
{
opj_image_destroy(jpx);
fz_throw("image components have different width");
}
if (jpx->comps[k].h != jpx->comps[0].h)
{
opj_image_destroy(jpx);
fz_throw("image components have different height");
}
if (jpx->comps[k].prec != jpx->comps[0].prec)
{
opj_image_destroy(jpx);
fz_throw("image components have different precision");
}
}
n = jpx->numcomps;
w = jpx->comps[0].w;
h = jpx->comps[0].h;
depth = jpx->comps[0].prec;
sgnd = jpx->comps[0].sgnd;
if (jpx->color_space == OPJ_CLRSPC_SRGB && n == 4) { n = 3; a = 1; }
else if (jpx->color_space == OPJ_CLRSPC_SYCC && n == 4) { n = 3; a = 1; }
else if (n == 2) { n = 1; a = 1; }
else if (n > 4) { n = 4; a = 1; }
else { a = 0; }
if (defcs)
{
if (defcs->n == n)
{
colorspace = defcs;
}
else
{
fz_warn("jpx file and dict colorspaces do not match");
defcs = NULL;
}
}
if (!defcs)
{
switch (n)
{
case 1: colorspace = pdf_devicegray; break;
case 3: colorspace = pdf_devicergb; break;
case 4: colorspace = pdf_devicecmyk; break;
}
}
//error = fz_new_pixmap(&img, colorspace, w, h);
//if (error)
// return error;
pdf_logimage("colorspace handled\n");
int bpc = 1;
if (colorspace) {
bpc = 1 + colorspace->n;
};
pdf_logimage("w = %d, bpc = %d, h = %d\n", w, bpc, h);
img->samples = fz_newbuffer(w * bpc * h);
//opj_image_destroy(jpx);
//fz_throw("out of memory loading jpx");
p = (char*)img->samples->bp;
pdf_logimage("start to deal with samples");
for (y = 0; y < h; y++)
{
for (x = 0; x < w; x++)
{
for (k = 0; k < n + a; k++)
{
v = jpx->comps[k].data[y * w + x];
if (sgnd)
v = v + (1 << (depth - 1));
if (depth > 8)
v = v >> (depth - 8);
*p++ = v;
}
if (!a)
*p++ = 255;
}
}
img->samples->wp = p;
pdf_logimage("start to deal with samples succeeded");
opj_image_destroy(jpx);
// if (a)
// {
// if (n == 4)
// {
// fz_pixmap *tmp = fz_new_pixmap(ctx, fz_device_rgb(ctx), w, h);
// fz_convert_pixmap(ctx, tmp, img);
// fz_drop_pixmap(ctx, img);
// img = tmp;
// }
// fz_premultiply_pixmap(ctx, img);
// }
return fz_okay;
}
The render code:
JNIEXPORT jbyteArray JNICALL Java_org_vudroid_pdfdroid_codec_PdfPage_drawPage
(JNIEnv *env, jclass clazz, jlong dochandle, jlong pagehandle)
{
renderdocument_t *doc = (renderdocument_t*) dochandle;
renderpage_t *page = (renderpage_t*) pagehandle;
//DEBUG("PdfView(%p).drawpage(%p, %p)", this, doc, page);
fz_error error;
fz_matrix ctm;
fz_irect viewbox;
fz_pixmap *pixmap;
jfloat *matrix;
jint *viewboxarr;
jint *dimen;
jint *buffer;
int length, val;
pixmap = nil;
/* initialize parameter arrays for MuPDF */
ctm.a = 1;
ctm.b = 0;
ctm.c = 0;
ctm.d = 1;
ctm.e = 0;
ctm.f = 0;
// matrix = (*env)->GetPrimitiveArrayCritical(env, matrixarray, 0);
// ctm.a = matrix[0];
// ctm.b = matrix[1];
// ctm.c = matrix[2];
// ctm.d = matrix[3];
// ctm.e = matrix[4];
// ctm.f = matrix[5];
// (*env)->ReleasePrimitiveArrayCritical(env, matrixarray, matrix, 0);
// DEBUG("Matrix: %f %f %f %f %f %f",
// ctm.a, ctm.b, ctm.c, ctm.d, ctm.e, ctm.f);
// viewboxarr = (*env)->GetPrimitiveArrayCritical(env, viewboxarray, 0);
// viewbox.x0 = viewboxarr[0];
// viewbox.y0 = viewboxarr[1];
// viewbox.x1 = viewboxarr[2];
// viewbox.y1 = viewboxarr[3];
// (*env)->ReleasePrimitiveArrayCritical(env, viewboxarray, viewboxarr, 0);
// DEBUG("Viewbox: %d %d %d %d",
// viewbox.x0, viewbox.y0, viewbox.x1, viewbox.y1);
viewbox.x0 = 0;
viewbox.y0 = 0;
viewbox.x1 = 595;
viewbox.y1 = 841;
/* do the rendering */
DEBUG("doing the rendering...");
//buffer = (*env)->GetPrimitiveArrayCritical(env, bufferarray, 0);
// do the actual rendering:
error = fz_rendertree(&pixmap, doc->rast, page->page->tree,
ctm, viewbox, 1);
/* evil magic: we transform the rendered image's byte order
*/
int x, y;
if (bmpdata)
fz_free(bmpdata);
bmpstride = ((pixmap->w * 3 + 3) / 4) * 4;
bmpdata = fz_malloc(pixmap->h * bmpstride);
DEBUG("inside drawpage, bmpstride = %d, pixmap->w = %d, pixmap->h = %d\n", bmpstride, pixmap->w, pixmap->h);
if (!bmpdata)
return;
for (y = 0; y < pixmap->h; y++)
{
unsigned char *p = bmpdata + y * bmpstride;
unsigned char *s = pixmap->samples + y * pixmap->w * 4;
for (x = 0; x < pixmap->w; x++)
{
p[x * 3 + 0] = s[x * 4 + 3];
p[x * 3 + 1] = s[x * 4 + 2];
p[x * 3 + 2] = s[x * 4 + 1];
}
}
FILE* fp = fopen("/sdcard/drawpage", "wb");
fwrite(bmpdata, pixmap->h * bmpstride, 1, fp);
fclose(fp);
jbyteArray array = (*env)->NewByteArray(env, pixmap->h * bmpstride);
(*env)->SetByteArrayRegion(env, array, 0, pixmap->h * bmpstride, bmpdata);
// if(!error) {
// DEBUG("Converting image buffer pixel order");
// length = pixmap->w * pixmap->h;
// unsigned int *col = pixmap->samples;
// int c = 0;
// for(val = 0; val < length; val++) {
// col[val] = ((col[val] & 0xFF000000) >> 24) |
// ((col[val] & 0x00FF0000) >> 8) |
// ((col[val] & 0x0000FF00) << 8);
// }
// winconvert(pixmap);
// }
// (*env)->ReleasePrimitiveArrayCritical(env, bufferarray, buffer, 0);
fz_free(pixmap);
if (error) {
DEBUG("error!");
throw_exception(env, "error rendering page");
}
DEBUG("PdfView.drawPage() done");
return array;
}
I have compare the jpx output samples to the mupdf-1.5 windows, it is the same, but the colorspace of original jpx have gone.
Could help me to get the colorspace back?
It seems you are trying to use an old version of MuPDF with some bits pulled in from a more recent version. TO be honest that's hardly likely to work. I would also guess that its not the OpenJPEG library causing your problem, since the image appears, but converted to grayscale.
Have you tried opening the file in the current version of MuPDF ? Does it work ?
If so then it seems to me your correct approach should be to use the current code, not try and bolt pieces onto an older version.

QuadTree or KD Tree for objective c? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I'm looking a while for a decent piece of code to use in my app, in one of those algorithms.
I found this example: http://rosettacode.org/wiki/K-d_tree#C
But when I put the code in xcode, I get an errors, for example:
"use of undeclared identifier", "expected ';' at the end of declaration".
I guess a header file is missing?
I copied the code from the link and made a minor edit which moved
"swap" from being an inline nested function to a static function.
Compiled with "gcc -C99 file.c" and it compiled ok. So, no, it doesn't
need some include file. Maybe you mis pasted it.
If you are happy with this answer, you could accept it. Thanks.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#define MAX_DIM 3
struct kd_node_t{
double x[MAX_DIM];
struct kd_node_t *left, *right;
};
inline double
dist(struct kd_node_t *a, struct kd_node_t *b, int dim)
{
double t, d = 0;
while (dim--) {
t = a->x[dim] - b->x[dim];
d += t * t;
}
return d;
}
static void swap(struct kd_node_t *x, struct kd_node_t *y) {
double tmp[MAX_DIM];
memcpy(tmp, x->x, sizeof(tmp));
memcpy(x->x, y->x, sizeof(tmp));
memcpy(y->x, tmp, sizeof(tmp));
}
/* see quickselect method */
struct kd_node_t*
find_median(struct kd_node_t *start, struct kd_node_t *end, int idx)
{
if (end <= start) return NULL;
if (end == start + 1)
return start;
struct kd_node_t *p, *store, *md = start + (end - start) / 2;
double pivot;
while (1) {
pivot = md->x[idx];
swap(md, end - 1);
for (store = p = start; p < end; p++) {
if (p->x[idx] < pivot) {
if (p != store)
swap(p, store);
store++;
}
}
swap(store, end - 1);
/* median has duplicate values */
if (store->x[idx] == md->x[idx])
return md;
if (store > md) end = store;
else start = store;
}
}
struct kd_node_t*
make_tree(struct kd_node_t *t, int len, int i, int dim)
{
struct kd_node_t *n;
if (!len) return 0;
if ((n = find_median(t, t + len, i))) {
i = (i + 1) % dim;
n->left = make_tree(t, n - t, i, dim);
n->right = make_tree(n + 1, t + len - (n + 1), i, dim);
}
return n;
}
/* global variable, so sue me */
int visited;
void nearest(struct kd_node_t *root, struct kd_node_t *nd, int i, int dim,
struct kd_node_t **best, double *best_dist)
{
double d, dx, dx2;
if (!root) return;
d = dist(root, nd, dim);
dx = root->x[i] - nd->x[i];
dx2 = dx * dx;
visited ++;
if (!*best || d < *best_dist) {
*best_dist = d;
*best = root;
}
/* if chance of exact match is high */
if (!*best_dist) return;
if (++i >= dim) i = 0;
nearest(dx > 0 ? root->left : root->right, nd, i, dim, best, best_dist);
if (dx2 >= *best_dist) return;
nearest(dx > 0 ? root->right : root->left, nd, i, dim, best, best_dist);
}
#define N 1000000
#define rand1() (rand() / (double)RAND_MAX)
#define rand_pt(v) { v.x[0] = rand1(); v.x[1] = rand1(); v.x[2] = rand1(); }
int main(void)
{
int i;
struct kd_node_t wp[] = {
{{2, 3}}, {{5, 4}}, {{9, 6}}, {{4, 7}}, {{8, 1}}, {{7, 2}}
};
struct kd_node_t this = {{9, 2}};
struct kd_node_t *root, *found, *million;
double best_dist;
root = make_tree(wp, sizeof(wp) / sizeof(wp[1]), 0, 2);
visited = 0;
found = 0;
nearest(root, &this, 0, 2, &found, &best_dist);
printf(">> WP tree\nsearching for (%g, %g)\n"
"found (%g, %g) dist %g\nseen %d nodes\n\n",
this.x[0], this.x[1],
found->x[0], found->x[1], sqrt(best_dist), visited);
million = calloc(N, sizeof(struct kd_node_t));
srand(time(0));
for (i = 0; i < N; i++) rand_pt(million[i]);
root = make_tree(million, N, 0, 3);
rand_pt(this);
visited = 0;
found = 0;
nearest(root, &this, 0, 3, &found, &best_dist);
printf(">> Million tree\nsearching for (%g, %g, %g)\n"
"found (%g, %g, %g) dist %g\nseen %d nodes\n",
this.x[0], this.x[1], this.x[2],
found->x[0], found->x[1], found->x[2],
sqrt(best_dist), visited);
/* search many random points in million tree to see average behavior.
tree size vs avg nodes visited:
10 ~ 7
100 ~ 16.5
1000 ~ 25.5
10000 ~ 32.8
100000 ~ 38.3
1000000 ~ 42.6
10000000 ~ 46.7 */
int sum = 0, test_runs = 100000;
for (i = 0; i < test_runs; i++) {
found = 0;
visited = 0;
rand_pt(this);
nearest(root, &this, 0, 3, &found, &best_dist);
sum += visited;
}
printf("\n>> Million tree\n"
"visited %d nodes for %d random findings (%f per lookup)\n",
sum, test_runs, sum/(double)test_runs);
// free(million);
return 0;
}